使用pandas进行简单数据处理的常用指令
一、背景
pandas是基于numpy的一种工具,是为解决数据分析任务而创建的。pandas提供了大量实用的函数用于分析数据,具体可参考官方文档。官网也有基础入门的十分钟指导,具体可见:10 minutes to pandas。
二、常用场景
1. 文件输入输出
pandas提供大量方便的IO操作,以读写csv文件为例:
# 读csv文件
import pandas as pd
df = pd.read_csv('filename.csv')
# 写csv文件,不输出索引
df.to_csv('target.csv', index=False)
# 写csv文件,输出索引
df.to_csv('target.csv', index=True)
上面代码中df是pandas.DataFrame的一个实例。
读写excel文件的方式与读写csv文件类似。读excel文件此处不再赘述,可参考官方文档pandas.read_excel。但写excel就需要注意了,我们有时候有需要将处理好的几份数据(DataFrame)写入到同一个excel表格中,以sheet区别,这时候需要使用下面的写法:
with pd.ExcelWriter('filename.xlsx') as writer:
df1.to_excel(writer, 'sheet_name_1')
df2.to_excel(writer, 'sheet_name_2')
上面的代码中,将df1写到filename.xlsx的sheet_name_1表,将df2写到filename.xlsx的sheet_name_2表。如果使用以下的写法,不使用with语句,则后一次写入会把前一次写入覆盖。即filename.xlsx只有一个表sheet_name_2
df1.to_excel('filename.xlsx', 'sheet_name_1')
df2.to_excel('filename.xlsx', 'sheet_name_2')
2. 获取某行、某列、某个位置的数据
要获取某行的数据,可以直接使用下标,如下取前面两行的数据:
>>> df
name toy born
0 Alfred NaN NaT
1 Batman Batmobile 1940-04-25
2 Catwoman Bullwhip NaT
>>> df[0:2]
name toy born
0 Alfred NaN NaT
1 Batman Batmobile 1940-04-25
如果要获取某列的数据,可以直接使用列名,如下取toy列的数据:
>>> df
name toy born
0 Alfred NaN NaT
1 Batman Batmobile 1940-04-25
2 Catwoman Bullwhip NaT
>>> df['name']
0 Alfred
1 Batman
2 Catwoman
Name: name, dtype: object
如果要获取某两列的数据,可以直接列名的列表,如下取toy列和born列的数据:
>>> df[['name','born']]
name born
0 Alfred NaT
1 Batman 1940-04-25
2 Catwoman NaT
结合前面几种情况,如果想取某列某行,如取第3行的toy列的数据,可以执行如下指令:
>>> df
name toy born
0 Alfred NaN NaT
1 Batman Batmobile 1940-04-25
2 Catwoman Bullwhip NaT
>>> df[2:3]['born']
2 NaT
Name: born, dtype: datetime64[ns]
如果想要获取某列中某些范围的数据,可以直接使用条件判断,如下:
>>> data = {'Name': ['Jai', 'Princi', 'Gaurav', 'Anuj'],
... 'Height': [5.1, 6.2, 5.1, 5.2],
... 'Qualification': ['Msc', 'MA', 'Msc', 'Msc']}
>>> df = pd.DataFrame(data)
>>> df
Name Height Qualification
0 Jai 5.1 Msc
1 Princi 6.2 MA
2 Gaurav 5.1 Msc
3 Anuj 5.2 Msc
>>> df[df['Height'] == 5.1]
Name Height Qualification
0 Jai 5.1 Msc
2 Gaurav 5.1 Msc
>>> df[df['Height'] > 5.1]
Name Height Qualification
1 Princi 6.2 MA
3 Anuj 5.2 Msc
3. 对某列数据进行排序
对数据进行排序主要使用DataFrame.sort_values接口,常用的是对某一列进行升序或降序排列,如下:
import pandas as pd
import numpy as np
df = pd.DataFrame({
'col1': ['A', 'A', 'B', np.nan, 'D', 'C'],
'col2': [2, 1, 9, 8, 7, 4],
'col3': [0, 1, 9, 4, 2, 3],
'col4': ['a', 'B', 'c', 'D', 'e', 'F']
})
df
df的打印值为:
>>> df
col1 col2 col3 col4
0 A 2 0 a
1 A 1 1 B
2 B 9 9 c
3 NaN 8 4 D
4 D 7 2 e
5 C 4 3 F
对第一列进行升序排序:
>>> df.sort_values(by=['col1'])
col1 col2 col3 col4
0 A 2 0 a
1 A 1 1 B
2 B 9 9 c
5 C 4 3 F
4 D 7 2 e
3 NaN 8 4 D
对第一列进行降序排序:
>>> df.sort_values(by=['col1'], ascending=False)
col1 col2 col3 col4
4 D 7 2 e
5 C 4 3 F
2 B 9 9 c
0 A 2 0 a
1 A 1 1 B
3 NaN 8 4 D
从上面的两个例子中可以发现空值(NaN)无论是升序还是降序排序都是排在数据集尾部的。如果想把空值排在前面,可以指定参数na_position的值为first,如下:
>>> df.sort_values(by=['col1'], ascending=False, na_position='first')
col1 col2 col3 col4
3 NaN 8 4 D
4 D 7 2 e
5 C 4 3 F
2 B 9 9 c
0 A 2 0 a
1 A 1 1 B
另外一个可能忽略的点是,如果sort_values不指定inplace参数,即原地排序,那么pandas排序时并不会修改原数据集的值,而是将新值返回,如下:
>>> df1=df.sort_values(by=['col1'], ascending=False, na_position='first')
>>> df
col1 col2 col3 col4
0 A 2 0 a
1 A 1 1 B
2 B 9 9 c
3 NaN 8 4 D
4 D 7 2 e
5 C 4 3 F
4. 去除列中的空值
去除数据集中列的空值主要使用DataFrame.dropna()函数,即drop nan。如下第2列和第3列中均有空值,涉及第1行和第3行。因此在执行dropna之后,只保留了第二行的数据:
>>> df = pd.DataFrame({"name": ['Alfred', 'Batman', 'Catwoman'],
... "toy": [np.nan, 'Batmobile', 'Bullwhip'],
... "born": [pd.NaT, pd.Timestamp("1940-04-25"),
... pd.NaT]})
>>> df
name toy born
0 Alfred NaN NaT
1 Batman Batmobile 1940-04-25
2 Catwoman Bullwhip NaT
>>> df.dropna()
name toy born
1 Batman Batmobile 1940-04-25
若要指定只去除某一列中的空值,可以使用subset参数。如下指定去除toy列的空值:
>>> df.dropna(subset='toy')
name toy born
1 Batman Batmobile 1940-04-25
2 Catwoman Bullwhip NaT
5. 计数
pandas的计数使用DataFrame.value_counts()接口。使用方法比较简单,如果想指定对某一列进行计数,在value_counts的subset参数中指定即可;如果无需指定对某一列进行计数,可直接调用该函数,如下:
>>> df = pd.DataFrame({'first_name': ['John', 'Anne', 'John', 'Beth'],
... 'middle_name': ['Smith', pd.NA, pd.NA, 'Louise']})
>>> df
first_name middle_name
0 John Smith
1 Anne <NA>
2 John <NA>
3 Beth Louise
>>> df.value_counts()
first_name middle_name
Beth Louise 1
John Smith 1
Name: count, dtype: int64
>>> df.value_counts(dropna=False)
first_name middle_name
Anne NaN 1
Beth Louise 1
John Smith 1
NaN 1
Name: count, dtype: int64
>>> df.value_counts(subset='first_name')
first_name
John 2
Anne 1
Beth 1
Name: count, dtype: int64
如果想取某个值的计数值,则可以直接使用下标指定想获取计数的值即可,如下:
>>> df.value_counts(subset='first_name')['John']
2
6. 行的连接
数据行的连接是使用pandas.concat()接口,如下:
>>> s1 = pd.Series(['a', 'b'])
>>> s2 = pd.Series(['c', 'd'])
>>> pd.concat([s1, s2])
0 a
1 b
0 c
1 d
dtype: object
7. 列的连接
列的连接更简单,直接使用赋值语句即可。如下:
>>> data = {'Name': ['Jai', 'Princi', 'Gaurav', 'Anuj'],
... 'Height': [5.1, 6.2, 5.1, 5.2],
... 'Qualification': ['Msc', 'MA', 'Msc', 'Msc']}
>>> df = pd.DataFrame(data)
>>> address = ['Delhi', 'Bangalore', 'Chennai', 'Patna']
>>> df['Address'] = address
>>> df
Name Height Qualification Address
0 Jai 5.1 Msc Delhi
1 Princi 6.2 MA Bangalore
2 Gaurav 5.1 Msc Chennai
3 Anuj 5.2 Msc Patna