文章目录
一、简介
这里简单介绍了创建Series和DataFrame的几种方法,这里简单介绍了查找数据的几种方法,这里简单介绍了pandas汇总和计算描述统计的几种方法。本文继续介绍一些pandas常用的属性、方法和函数。
二、常用的属性、方法和函数
先创建一个DataFrame,作为例子演示用。
import pandas as pd
data = {'name': ['apolo', 'adm', 'bolon', 'ali', 'cathy', 'devn', 'elov'],
'age': [18, 29, 32, 28, 34, 19, None],
'sex': ['male', 'female', 'male', 'male', 'female', 'male', 'female'],
'weight': [67, 78, 87, 59, 90, 101, 78],
'height': [170, 189, 190, 179, None, 160, 185]}
df = pd.DataFrame(data, index=['a', 'b', 'c', 'd', 'e','f', 'g'])
df
输出:
name age sex weight height
a apolo 18.0 male 67 170.0
b adm 29.0 female 78 189.0
c bolon 32.0 male 87 190.0
d ali 28.0 male 59 179.0
e cathy 34.0 female 90 NaN
f devn 19.0 male 101 160.0
g elov NaN female 78 185.0
2.1 shape
返回Series和DataFrame的大小。
DataFrame
df.shape
输出:是个元组类型,可继续用df.shape[0]
获取第一个值,用df.shape[1]
获取第二个值
(7, 5)
Series
df['age'].shape
输出:是个元组类型,可继续用df.shape[0]
获取第一个值,但不能用df.shape[1]
获取第二个值
(7,)
2.2 排序
pandas中的排序一般用的比较多的有三种:索引排序——sort_index()
,值排序——sort_values
,排名——rank()
,接下来逐一介绍:
2.2.1 索引排序——sort_index()
索引排序,顾名思义就是将数据按照索引名进行排序,下面给出几个例子具体说明一下。
原DataFrame:
name age sex weight height
a apolo 18.0 male 67 170.0
i adm 29.0 female 78 189.0
c bolon 32.0 male 87 190.0
d ali 28.0 male 59 179.0
h cathy 34.0 female 90 NaN
f devn 19.0 male 101 160.0
g elov NaN female 78 185.0
df.sort_index()
输出:默认是对行索引进行升序排列。可通过设置axis=1
按照列索引名排序,此时会改变列的顺序,而不是行的顺序。可通过设置ascending=False
进行降序排列。默认的是不改变原df的顺序,可通过设置inplace=True
进行改变原df的顺序。Series也类似,只不过不能设置axis=1
。
name age sex weight height
a apolo 18.0 male 67 170.0
c bolon 32.0 male 87 190.0
d ali 28.0 male 59 179.0
f devn 19.0 male 101 160.0
g elov NaN female 78 185.0
h cathy 34.0 female 90 NaN
i adm 29.0 female 78 189.0
2.2.2 值排序——sort_values()
值排序和索引排序的用法及功能类似,只不过在运用值排序的时候需要指定按照哪一列或哪几列的值进行排序。
df.sort_values(by='age')
输出:按照age列的数据进行升序排序。当指定axis=1
时,传给by参数的是行索引的名字,此时按照那一行的数据进行排序;同样可指定ascending=False
进行降序排列,也可设置inplace=True
进行改变原df的顺序;也可传给by参数一个列表,此时将按照列表中名称的顺序,以此将数据进行排序。Series也类似,只不过不能设置axis=1
,也不用传入参数by。
name age sex weight height
i adm 18.0 female 78 189.0
f devn 19.0 male 101 160.0
g elov 28.0 female 78 185.0
a apolo 29.0 male 67 170.0
h cathy 32.0 female 90 NaN
c bolon 34.0 male 87 190.0
d ali NaN male 59 179.0
2.2.3 排名——rank()
前两个都是返回排序后的数据,rank()则是返回各个数据的排名,并不返回原数据。
df.rank()
输出:直接对DataFrame进行rank,会返回所有数据的排名。默认的是返回排名的平均值,即如果值相同,那么取这些值的排名的平均值作为这些值的排名(比如sex列,female值相同,应该排在前3,因此取(1+2+3)/3=2作为female的排名),可以通过method='first'
设为按值在原始数据中的出现顺序分配排名,只不过不支持非数值型数据。同样也有参数axis
,ascending
。
name age sex weight height
a 3.0 1.0 5.5 2.0 2.0
i 1.0 4.0 2.0 3.5 5.0
c 4.0 5.0 5.5 5.0 6.0
d 2.0 3.0 5.5 1.0 3.0
h 5.0 6.0 2.0 6.0 NaN
f 6.0 2.0 5.5 7.0 1.0
g 7.0 NaN 2.0 3.5 4.0
2.3 数据合并
pandas中数据合并一般包括pd.merge,pd.concat,下面逐一介绍它们。
2.3.1 merge()
关于pd.merge(),这篇文章讲的很详细,也很全面。另外需要补充说明的是,merge()和sql中表的连接很像,有个参数是how
,默认的是inner
,可选{'left', 'right', 'outer', 'inner', 'cross'}
,这个对应着sql中的连接方式,是内连接,还是左连接,右连接。
2.3.2 concat()
pd.concat(
objs: Union[Iterable[ForwardRef('NDFrame')], Mapping[Optional[Hashable], ForwardRef('NDFrame')]],
axis=0,
join='outer',
ignore_index: bool = False,
keys=None,
levels=None,
names=None,
verify_integrity: bool = False,
sort: bool = False,
copy: bool = True,
)
常用的参数:objs
是要合并的df或Series,可以将待合并的df放到一个列表里,一起传入,可以是两个df,也可以是多个df;axis=0
意思是默认按列合并,即取列名的并集或交集进行合并df,当设为1时,对行索引名取并集或交集进行合并df;join='outer'
意思是默认取并集,可设置为'inner'
改为取交集;ignore_index: bool = False
则是是否忽略索引名,默认不忽略,即用原索引名,当设为True时,用0,1,2,……代替;
通过几个例子来说明这个函数的用法。
先建立两个DataFrame:
data1 = {'name': ['apolo', 'adm', 'bolon', 'ali', 'cathy', 'devn', 'elov'],
'age': [18, 29, 32, 28, 34, 19, None],
'sex': ['male', 'female', 'male', 'male', 'female', 'male', 'female'],
'weight': [67, 78, 87, 59, 90, 101, 78],
'height': [170, 189, 190, 179, None, 160, 185]}
df1 = pd.DataFrame(data1, index=['a', 'i', 'c', 'd', 'h','f', 'g'])
df1
输出:df1
name age sex weight height
a apolo 18.0 male 67 170.0
i adm 29.0 female 78 189.0
c bolon 32.0 male 87 190.0
d ali 28.0 male 59 179.0
h cathy 34.0 female 90 NaN
f devn 19.0 male 101 160.0
g elov NaN female 78 185.0
data2 = {'name': ['apolo', 'adm', 'bolon', 'ali', 'cathy'],
'age': [18, 29, 32, 28, None],
'sex': ['male', 'male', 'female', 'male', 'female'],
'country': ['BR', 'MX', 'CL', 'BR', 'CO']}
df2 = pd.DataFrame(data2, index=['a', 'b', 'm', 'n', 'h'])
df2
输出:df2
name age sex country
a apolo 18.0 male BR
b adm 29.0 male MX
m bolon 32.0 female CL
n ali 28.0 male BR
h cathy NaN female CO
直接用concat()将上述两个df进行合并。
result = pd.concat([df1, df2])
result
输出:可以看到,新的数据集的行名是它们的并集。对于只在一个df中出现的列(如country,只原本在df2中出现),该列在另一个df对应的索引的值是空值。此时新的数据集的行索引为原数据集的所有行索引,可以重复。
name age sex weight height country
a apolo 18.0 male 67.0 170.0 NaN
i adm 29.0 female 78.0 189.0 NaN
c bolon 32.0 male 87.0 190.0 NaN
d ali 28.0 male 59.0 179.0 NaN
h cathy 34.0 female 90.0 NaN NaN
f devn 19.0 male 101.0 160.0 NaN
g elov NaN female 78.0 185.0 NaN
a apolo 18.0 male NaN NaN BR
b adm 29.0 male NaN NaN MX
m bolon 32.0 female NaN NaN CL
n ali 28.0 male NaN NaN BR
h cathy NaN female NaN NaN CO
设置axis=1
result = pd.concat([df1, df2], axis=1)
result
输出:可以看到,此时行索引名是原数据集行索引的并集,对于只在一个df中出现的行索引名(如n,只原本在df2中出现),该行在另一个df对应的列的值是空值。此时新的数据集的列名为原数据集的所有列名,可以重复。
name age sex weight height name age sex country
a apolo 18.0 male 67.0 170.0 apolo 18.0 male BR
i adm 29.0 female 78.0 189.0 NaN NaN NaN NaN
c bolon 32.0 male 87.0 190.0 NaN NaN NaN NaN
d ali 28.0 male 59.0 179.0 NaN NaN NaN NaN
h cathy 34.0 female 90.0 NaN cathy NaN female CO
f devn 19.0 male 101.0 160.0 NaN NaN NaN NaN
g elov NaN female 78.0 185.0 NaN NaN NaN NaN
b NaN NaN NaN NaN NaN adm 29.0 male MX
m NaN NaN NaN NaN NaN bolon 32.0 female CL
n NaN NaN NaN NaN NaN ali 28.0 male BR
设置join='inner'
result = pd.concat([df1, df2], join='inner')
result
输出:可以看到此时的列名为原数据集列名的交集,而行索引依旧是原数据集的所有行索引,可以重复。
name age sex
a apolo 18.0 male
i adm 29.0 female
c bolon 32.0 male
d ali 28.0 male
h cathy 34.0 female
f devn 19.0 male
g elov NaN female
a apolo 18.0 male
b adm 29.0 male
m bolon 32.0 female
n ali 28.0 male
h cathy NaN female
设置ignore_index=True
result = pd.concat([df1, df2], join='inner', ignore_index=True)
result
输出:可以看到此时的行索引变为了0, 1, 2, ……,11,而不是原数据集的行索引;同样,当设置axis=1时,列索引即列名会变为0,1, 2,……
name age sex
0 apolo 18.0 male
1 adm 29.0 female
2 bolon 32.0 male
3 ali 28.0 male
4 cathy 34.0 female
5 devn 19.0 male
6 elov NaN female
7 apolo 18.0 male
8 adm 29.0 male
9 bolon 32.0 female
10 ali 28.0 male
11 cathy NaN female
2.4 索引
这一小节将介绍和索引相关的几个方法。
2.4.1 reset_index()
df.reset_index()的功能是将原df的行索引变为一列加入到df中,这一列的列名为index,同时,df的索引将会变为默认索引,即0,1,2,……
原df2:
name age sex country
a apolo 18.0 male BR
b adm 29.0 male MX
m bolon 32.0 female CL
n ali 28.0 male BR
h cathy NaN female CO
进行reset_index()
:
df2.reset_index()
输出:可以看到,原索引’a, b, m, n, h’变成了一个列,列名为’index’,而默认索引0, 1, 2, 3, 4成为了新的索引。
index name age sex country
0 a apolo 18.0 male BR
1 b adm 29.0 male MX
2 m bolon 32.0 female CL
3 n ali 28.0 male BR
4 h cathy NaN female CO
reset_index()的一些常用的参数为:drop = False, inplace = False
。其中,drop = False
的作用是是否丢弃掉’index’列,当设为True时,reset_index()的作用是仅将行索引变为默认索引0,1,……,而df的列和值没有改变;inplace = False
的作用是是否替换原df,当设为True时,reset_index()将改变原df,否则只是返回一个改变后的df,而不改变原df。
设置drop = True
:
df2.reset_index(drop=True)
输出:可以看到和df2的区别仅在于行索引名的不同。
name age sex country
0 apolo 18.0 male BR
1 adm 29.0 male MX
2 bolon 32.0 female CL
3 ali 28.0 male BR
4 cathy NaN female CO
设置inplace = True
:
df2.reset_index(inplace=True)
df2
输出:当执行df2.reset_index(inplace=True)
时,不会有输出,是将df2进行了改变。
index name age sex country
0 a apolo 18.0 male BR
1 b adm 29.0 male MX
2 m bolon 32.0 female CL
3 n ali 28.0 male BR
4 h cathy NaN female CO
2.4.2 rename()
rename()用于改变df行、列的标签名,可以传入一个一对一的字典或函数,在数据预处理中比较常用。
常用参数:默认是改变行索引名,要想改变列索引名,可以用mapper=None, axis=1
或columns=None
,传入mapper=None, index=None, columns=None
的参数是一一映射的字典或一一映射的函数;inplace=False
则是决定是否将结果返回值赋值给原df;而errors='ignore'
则决定了报错的方式,即当传入的参数中包含索引列没有的值时,是否报错,默认不报错,改为``errors=‘raise’`时,进行报错。
需要注意的是,可以只改变部分行索引或列索引的名称,传入由部分索引名作为键的字典或函数即可,此时,对于未传入的索引名,并不会改变,会保持原样。
mapper=None, index=None, columns=None, axis=None, copy=True, inplace=False, level=None, errors='ignore',
原df2:
name age sex country
a apolo 18.0 male BR
b adm 29.0 male MX
m bolon 32.0 female CL
n ali 28.0 male BR
h cathy NaN female CO
改变行索引:
d = {'a': 'apple',
'b' : 'banana',
'm' : 'man',
'n': 'north',
'h': 'hello'}
df2.rename(d)
输出:可以看到,已经将行索引名按照字典的映射关系进行了改变,用df2.rename(index=d)
同样可以达到这个效果,更推荐用df2.rename(index=d)
这种形式。
name age sex country
apple apolo 18.0 male BR
banana adm 29.0 male MX
man bolon 32.0 female CL
north ali 28.0 male BR
hello cathy NaN female CO
2.4.3 reindex()
reindex()用于重置行索引或列索引,即将df或Series的行或列按照我们想要的顺序排列。
常用参数:默认是重置行索引,可通过参数columns
或axis=1
重置列索引;当重置后的索引和原索引不同时,该索引对应的值为空值,此时可利用参数fill_value
将缺失的值统一填充为指定的值,也可以在最后加上ffill()方法或bfill()方法进行向前或向后填充。
需要注意的是,该方法并不会直接改变原df。
df.reindex(
labels=None,
index=None,
columns=None,
axis=None,
method=None,
copy=True,
level=None,
fill_value=nan,
limit=None,
tolerance=None,
)
原df2:
name age sex country
a apolo 18.0 male BR
b adm 29.0 male MX
m bolon 32.0 female CL
n ali 28.0 male BR
h cathy NaN female CO
重置列索引:
new_index = ['name', 'age', 'country', 'sex']
df2.reindex(columns = new_index)
输出:可以看到改变了sex列和country列的顺序。
name age country sex
a apolo 18.0 BR male
b adm 29.0 MX male
m bolon 32.0 CL female
n ali 28.0 BR male
h cathy NaN CO female
缺失值填充:
new_index = ['name', 'age', 'sex', 'married']
df2.reindex(columns = new_index, fill_value=1)
输出:将原列索引‘country’替换为了‘married’,此时会变成空值,但用fill_value=1
进行了填充,因此缺失值都变为了1.
name age sex married
a apolo 18.0 male 1
b adm 29.0 male 1
m bolon 32.0 female 1
n ali 28.0 male 1
h cathy NaN female 1
向前/后填充缺失值:只有重置行索引时可以这样填充,重置列索引时不可以。
new_index = ['a', 'b', 'c', 'd', 'm']
df2.reindex(new_index).ffill()
输出:可以看到,新的行索引’c’和‘d’的值和’b’的相同,当使用df2.reindex(new_index).bfill()
时,则会和’m’的相同。ffill时,如果待填充的前一行是空值,则会继续向上找不是空值的进行填充,如果最上面是空值,那么填充的也是空值,同时,原数据有空值的话,原数据也会进行填充。bfill时也类似。
name age sex country
a apolo 18.0 male BR
b adm 29.0 male MX
c adm 29.0 male MX
d adm 29.0 male MX
m bolon 32.0 female CL