该文档记录一些Pandas对已有数据进行合并排序等操作的方法。 ## 重置行列标签

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import pandas as pd
import numpy as np
N=20
df = pd.DataFrame({
'A': pd.date_range(start='2016-01-01',periods=N,freq='D'),
'x': np.linspace(0,stop=N-1,num=N),
'y': np.random.rand(N),
'C': np.random.choice(['Low','Medium','High'],N).tolist(),
'D': np.random.normal(100, 10, size=(N)).tolist()
})
#重置行、列索引标签
df_reindexed = df.reindex(index=[0,2,5], columns=['A', 'C', 'B'])
print(df_reindexed)
# A C B
# 0 2020-12-07 Medium NaN
# 2 2020-12-09 Low NaN
# 5 2020-12-12 High NaN

a= a.reindex_like(b) 可以把a的index重置为与b相等的

重命名标签 用 rename()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import pandas as pd
import numpy as np
df1 = pd.DataFrame(np.random.randn(6,3),columns=['col1','col2','col3'])
print (df1)
#对行和列重新命名
print (df1.rename(columns={'col1' : 'c1', 'col2' : 'c2'},index = {0 : 'apple', 1 : 'banana', 2 : 'durian'}))

# col1 col2 col3
# 0 -1.762133 -0.636819 -0.309572
# 1 -0.093965 -0.924387 -2.031457
# 2 -1.231485 -0.738667 1.415724
# 3 -0.826322 0.206574 -0.731701
# 4 1.863816 -0.175705 0.491907
# 5 0.677361 0.870041 -0.636518

# c1 c2 col3
# apple -1.762133 -0.636819 -0.309572
# banana -0.093965 -0.924387 -2.031457
# durian -1.231485 -0.738667 1.415724
# 3 -0.826322 0.206574 -0.731701
# 4 1.863816 -0.175705 0.491907
# 5 0.677361 0.870041 -0.636518

排序

按标签排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import pandas as pd
import numpy as np
#行标签乱序排列,列标签乱序排列
unsorted_df=pd.DataFrame(np.random.randn(10,2),index=[1,6,4,2,3,5,9,8,0,7],columns=['col2','col1'])
print(unsorted_df)
# col2 col1
# 1 0.252640 -1.219655
# 6 -1.192283 -0.765094
# 4 0.029277 -0.372222
# 2 -0.078161 -1.549456
# 3 0.500737 -0.445477
# 5 -0.952137 -0.129147
# 9 -1.748176 -1.792424
# 8 -0.675795 1.312546
# 0 0.528465 0.838617
# 7 -0.511180 2.226228
  • sort_index
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
sorted_df=unsorted_df.sort_index()#默认对行标签进行排序
print(sorted_df)
col2 col1
0 0.528465 0.838617
1 0.252640 -1.219655
2 -0.078161 -1.549456
3 0.500737 -0.445477
4 0.029277 -0.372222
5 -0.952137 -0.129147
6 -1.192283 -0.765094
7 -0.511180 2.226228
8 -0.675795 1.312546
9 -1.748176 -1.792424

sorted_df = unsorted_df.sort_index(ascending=False)#引入ascending参数实现倒序排序
col2 col1
9 -1.748176 -1.792424
8 -0.675795 1.312546
7 -0.511180 2.226228
6 -1.192283 -0.765094
5 -0.952137 -0.129147
4 0.029277 -0.372222
3 0.500737 -0.445477
2 -0.078161 -1.549456
1 0.252640 -1.219655
0 0.528465 0.838617

sorted_df=unsorted_df.sort_index(axis=1)# axis=1则按列进行排序。
print (sorted_df)
col1 col2
1 -1.219655 0.252640
6 -0.765094 -1.192283
4 -0.372222 0.029277
2 -1.549456 -0.078161
3 -0.445477 0.500737
5 -0.129147 -0.952137
9 -1.792424 -1.748176
8 1.312546 -0.675795
0 0.838617 0.528465
7 2.226228 -0.511180

import pandas as pd
import numpy as np
unsorted_df = pd.DataFrame({'col1':[2,1,1,1],'col2':[1,3,2,4]})
sorted_df = unsorted_df.sort_values(by='col1')#对col1进行排序
print (sorted_df)
col1 col2
1 1 3
2 1 2
3 1 4
0 2 1

sorted_df = unsorted_df.sort_values(by=['col1','col2'])#引入列表对两列进行排序
print (sorted_df)
col1 col2
2 1 2
1 1 3
3 1 4
0 2 1

排序算法

  • sort_values()

    提供了三种排序算法

    1. mergesort 归并
    2. heapsort 堆
    3. quicksort 快速
1
2
3
4
5
6
7
8
9
10
import pandas as pd
import numpy as np
unsorted_df = pd.DataFrame({'col1':[2,1,1,1],'col2':[1,3,2,4]})
sorted_df = unsorted_df.sort_values(by='col1' ,kind='mergesort')
print (sorted_df)
col1 col2
1 1 3
2 1 2
3 1 4
0 2 1

去重

df.drop_duplicates(subset=['A','B','C'],keep='first',inplace=True)

参数 功能
subset 表示要进去重的列名,默认为 None。
keep 有三个可选参数,分别是 first、last、False,默认为 first,表示只保留第一次出现的重复项,删除其余重复项,last 表示只保留最后一次出现的重复项,False 则表示删除所有重复项。
inplace 布尔值参数,默认为 False 表示删除重复项后返回一个副本,若为 Ture 则表示直接在原数据上删除重复项。
  • 首先创建一个有重复值的DataFrame
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import pandas as pd
data={

'A':[1,0,1,1],
'B':[0,2,5,0],
'C':[4,0,4,4],
'D':[1,0,1,1]
}
df=pd.DataFrame(data=data)
print(df)
A B C D
0 1 0 4 1
1 0 2 0 0
2 1 5 4 1
3 1 0 4 1

df.drop_duplicates()#默认保留第一次出现的重复值

A B C D
0 1 0 4 1
1 0 2 0 0
2 1 5 4 1

df.drop_duplicates(keep=False)#去除所有重复值
A B C D
1 0 2 0 0
2 1 5 4 1
df.drop_duplicates(subset=['B'],keep=False)#去除所有重复项,对于B列来说两个0是重复项

df.drop_duplicates(['B'],keep='last')#保留最后一个重复值

处理字符串的方法

函数名称 函数功能和描述
lower() 将的字符串转换为小写。
upper() 将的字符串转换为大写。
len() 得出字符串的长度。
strip() 去除字符串两边的空格(包含换行符)。
split() 用指定的分割符分割字符串。
cat(sep="") 用给定的分隔符连接字符串元素。
get_dummies() 返回一个带有独热编码值的 DataFrame 结构。
contains(pattern ) 如果子字符串包含在元素中,则为每个元素返回一个布尔值 True,否则为 False。
replace(a,b) 将值 a 替换为值 b。
count(pattern) 返回每个字符串元素出现的次数。
startswith(pattern) 如果 Series 中的元素以指定的字符串开头,则返回 True。
endswith(pattern) 如果 Series 中的元素以指定的字符串结尾,则返回 True。
findall(pattern) 以列表的形式返出现的字符串。
swapcase() 交换大小写。
islower() 返回布尔值,检查 Series 中组成每个字符串的所有字符是否都为小写。
issupper() 返回布尔值,检查 Series 中组成每个字符串的所有字符是否都为大写。
isnumeric() 返回布尔值,检查 Series 中组成每个字符串的所有字符是否都为数字。
repeat(value) 以指定的次数重复每个元素。
find(pattern) 返回字符串第一次出现的索引位置
  • 使用方法 Dataframe/Series.str.[上述的函数]

分组操作

  • 使用groupby() df.groupby("key") df.groupby("key",axis=1) df.groupby(["key1","key2"])
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import pandas as pd
import numpy as np
data = {'Name': ['John', 'Helen', 'Sona', 'Ella'],
'score': [82, 98, 91, 87],
'option_course': ['C#','Python','Java','C']}
df = pd.DataFrame(data)
#查看分组
print(df.groupby('score').groups)

{82: Int64Index([0], dtype='int64'),
87: Int64Index([3], dtype='int64'),
91: Int64Index([2], dtype='int64'),
98: Int64Index([1], dtype='int64')}

print(df.groupby(['Name','score']).groups)#指定多个标签
{('Ella', 87): Int64Index([3], dtype='int64'),
('Helen', 98): Int64Index([1], dtype='int64'),
('John', 82): Int64Index([0], dtype='int64'),
('Sona', 91): Int64Index([2], dtype='int64')}

通过 get_group() 方法可以选择组内的具体数据项:

1
2
3
4
5
6
7
8
9
10
11
12
import pandas as pd
import numpy as np
data = {'Name': ['John', 'Helen', 'Sona', 'Ella'],
'score': [82, 98, 91, 87],
'option_course': ['C#','Python','Java','C']}
df = pd.DataFrame(data)
#根据score来分组
grouped=df.groupby('score')
#根据对应组的数据值,选择一个组
print(grouped.get_group(91))
Name score option_course
2 Sona 91 Java

合并

使用 merge()
pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None,left_index=False, right_index=False, sort=True,suffixes=('_x', '_y'), copy=True)

参数名称 说明
left/right 两个不同的 DataFrame 对象。
on 指定用于连接的键(即列标签的名字),该键必须同时存在于左右两个 DataFrame 中,如果没有指定,并且其他参数也未指定, 那么将会以两个 DataFrame 的列名交集做为连接键。
left_on 指定左侧 DataFrame 中作连接键的列名。该参数在左、右列标签名不相同,但表达的含义相同时非常有用。
right_on 指定左侧 DataFrame 中作连接键的列名。
left_index 布尔参数,默认为 False。如果为 True 则使用左侧 DataFrame 的行索引作为连接键,若 DataFrame 具有多层索引(MultiIndex),则层的数量必须与连接键的数量相等。
right_index 布尔参数,默认为 False。如果为 True 则使用左侧 DataFrame 的行索引作为连接键。
how 要执行的合并类型,从 {'left', 'right', 'outer', 'inner'} 中取值,默认为“inner”内连接。
sort 布尔值参数,默认为True,它会将合并后的数据进行排序;若设置为 False,则按照 how 给定的参数值进行排序。
suffixes 字符串组成的元组。当左右 DataFrame 存在相同列名时,通过该参数可以在相同的列名后附加后缀名,默认为('_x','_y')。
copy 默认为 True,表示对数据进行复制。

Excemple

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import pandas as pd 
left = pd.DataFrame({
'id':[1,2,3,4],
'Name': ['Smith', 'Maiki', 'Hunter', 'Hilen'],
'subject_id':['sub1','sub2','sub4','sub6']})
right = pd.DataFrame({
'id':[1,2,3,4],
'Name': ['William', 'Albert', 'Tony', 'Allen'],
'subject_id':['sub2','sub4','sub3','sub6']})
print (left)
print (right)
id Name subject_id
0 1 Smith sub1
1 2 Maiki sub2
2 3 Hunter sub4
3 4 Hilen sub6

id Name subject_id
0 1 William sub2
1 2 Albert sub4
2 3 Tony sub3
3 4 Allen sub6

#通过on参数指定合并的键
print(pd.merge(left,right,on='id'))

id Name_x subject_id_x Name_y subject_id_y
0 1 Smith sub1 William sub2
1 2 Maiki sub2 Albert sub4
2 3 Hunter sub4 Tony sub3
3 4 Hilen sub6 Allen sub6
#多个键上合并
print(pd.merge(left,right,on=['id','subject_id']))
id Name_x subject_id Name_y
0 4 Hilen sub6 Mike

How参数

Merge方法 等效 SQL 描述
left LEFT OUTER JOIN 使用左侧对象的key
right RIGHT OUTER JOIN 使用右侧对象的key
outer FULL OUTER JOIN 使用左右两侧所有key的并集
inner INNER JOIN 使用左右两侧key的交集
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import pandas as pd 
left = pd.DataFrame({
'id':[1,2,3,4],
'Name': ['Smith', 'Maiki', 'Hunter', 'Hilen'],
'subject_id':['sub1','sub2','sub4','sub6']})
right = pd.DataFrame({
'id':[1,2,3,4],
'Name': ['Bill', 'Lucy', 'Jack', 'Mike'],
'subject_id':['sub2','sub4','sub3','sub6']})
#以left侧的subject_id为键
print(pd.merge(left,right,on='subject_id',how="left"))

id_x Name_x subject_id id_y Name_y
0 1 Smith sub1 NaN NaN
1 2 Maiki sub2 1.0 Bill
2 3 Hunter sub4 2.0 Lucy
3 4 Hilen sub6 4.0 Mike

#以right侧的subject_id为键
print(pd.merge(left,right,on='subject_id',how="right"))

id_x Name_x subject_id id_y Name_y
0 2.0 Maiki sub2 1 Bill
1 3.0 Hunter sub4 2 Lucy
2 4.0 Hilen sub6 4 Mike
3 NaN NaN sub3 3 Jack

#求出两个subject_id的并集,并作为键
print(pd.merge(left,right,on='subject_id',how="outer"))
id_x Name_x subject_id id_y Name_y
0 1.0 Smith sub1 NaN NaN
1 2.0 Maiki sub2 1.0 Bill
2 3.0 Hunter sub4 2.0 Lucy
3 4.0 Hilen sub6 4.0 Mike
4 NaN NaN sub3 3.0 Jack

#求出两个subject_id的交集,并将结果作为键
print(pd.merge(left,right,on='subject_id',how="inner"))
id_x Name_x subject_id id_y Name_y
0 2 Maiki sub2 1 Bill
1 3 Hunter sub4 2 Lucy
2 4 Hilen sub6 4 Mike

concat连接

pd.concat(objs,axis=0,join='outer',join_axes=None,ignore_index=False)

参数名称 说明
objs 一个序列或者是Series、DataFrame对象。
axis 表示在哪个轴方向上(行或者列)进行连接操作,默认 axis=0 表示行方向。
join 指定连接方式,取值为{"inner","outer"},默认为 outer 表示取并集,inner代表取交集。
ignore_index 布尔值参数,默认为 False,如果为 True,表示不在连接的轴上使用索引。
join_axes 表示索引对象的列表。

Excemple

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import pandas as pd
a= pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],
'B': ['B0', 'B1', 'B2', 'B3'],
'C': ['C0', 'C1', 'C2', 'C3'],
'D': ['D0', 'D1', 'D2', 'D3']},
index=[0, 1, 2, 3])
b= pd.DataFrame({'A': ['A4', 'A5', 'A6', 'A7'],
'B': ['B4', 'B5', 'B6', 'B7'],
'C': ['C4', 'C5', 'C6', 'C7'],
'D': ['D4', 'D5', 'D6', 'D7']},
index=[2,3,4,5])
#连接a与b
print(pd.concat([a,b])) 和append()相似
A B C D
0 A0 B0 C0 D0
1 A1 B1 C1 D1
2 A2 B2 C2 D2
3 A3 B3 C3 D3
2 A4 B4 C4 D4
3 A5 B5 C5 D5
4 A6 B6 C6 D6
5 A7 B7 C7 D7

#连接a与b,并给a,b连接一个指定的键
print(pd.concat([a,b],keys=['x','y']))
A B C D
x 0 A0 B0 C0 D0
1 A1 B1 C1 D1
2 A2 B2 C2 D2
3 A3 B3 C3 D3
y 2 A4 B4 C4 D1
3 A5 B5 C5 D2
4 A6 B6 C6 D5
5 A7 B7 C7 D6

#连接a与b,设置 ignore_index 等于 True
print(pd.concat([a,b],keys=['x','y'],ignore_index=True))

输出结果:
A B C D
0 A0 B0 C0 D0
1 A1 B1 C1 D1
2 A2 B2 C2 D2
3 A3 B3 C3 D3
4 A4 B4 C4 D1
5 A5 B5 C5 D2
6 A6 B6 C6 D5
7 A7 B7 C7 D6
此时的索引顺序被改变了,而且键 keys 指定的键也被覆盖了。

#沿着 axis=1,连接a与b
print(pd.concat([a,b],axis=1))

A B C D A B C D
0 A0 B0 C0 D0 NaN NaN NaN NaN
1 A1 B1 C1 D1 NaN NaN NaN NaN
2 A2 B2 C2 D2 NaN NaN NaN NaN
3 A3 B3 C3 D3 NaN NaN NaN NaN
2 NaN NaN NaN NaN A4 B4 C4 D1
3 NaN NaN NaN NaN A5 B5 C5 D2
4 NaN NaN NaN NaN A6 B6 C6 D5
5 NaN NaN NaN NaN A7 B7 C7 D6