Python 使用Pandas操作数据的常用函数方法


前言

本文主要介绍使用pandas对数据文件进行操作的一些常用且基础的函数。该篇文章适合对DataFrame结构有一定了解的读者阅读。使用函数前先导入pandas库import pandas as pd

一 创建DataFrame数据结构

# 方法一
df1 = pd.DataFrame({'id':[1,2,3],'name':['张三','李四','王五'],'age':[28,25,30]})
# 方法二
df2 = pd.DataFrame([{'id':1,'name':'张三','age':28},{'id':2,'name':'李四','age':25},{'id':1,'name':'王五','age':30}])
print(df1)
print(df2)

运行效果如下:

id  name   age
0   1   张三   28
1   2   李四   25
2   3   王五   30
   id  name   age
0   1   张三   28
1   2   李四   25
2   1   王五   30

二 保存DataFrame数据到本地

# 保存为csv
df.to_csv(filepath, index=False, header=True, encoding='utf_8_sig')
# 保存为excel
df.to_excel(filepath, index=False, header=True, encoding='utf_8_sig')

其中,filepath为要保存的文件地址,index为是否要保存行数的索引,header为是否要保存表头,encoding设置utf-8编码(防止出现中文乱码)。

三 将本地文件读取为DataFrame结构

# 读取excel文件
df1 = pd.read_excel(filepath1,header=2,sheet_name='Sheet1',skiprows=4)
# 读取csv文件
df2 = pd.read_csv(filepath2,header=2,skiprows=4)

filepath:文件路径;sheet_name:指定读取excel指定的表;header=2:将第三行作为表头开始。默认header=0,如果header=None表示为不要表头(获取的行数据用下标表示,如row[0],row[1]...);skiprows:跳过开头几行数据。

四 遍历DataFrame数据

使用DataFrame对象的iterrows()方法进行数据遍历。

# index为每一行的索引,row为每行对象
for index, row in df2.iterrows():
    print('这是第'+str(index)+'行数据')
    print(index,row[0],row[1],row[2])	# 按索引读取该行指定列数据
    print(row['id'], row['name'], row['age'])	# 按表头名读取该行指定列数据

运行效果如下:

这是第0行数据
1 张三 28
1 张三 28
这是第1行数据
2 李四 25
2 李四 25
这是第2行数据
1 王五 30
1 王五 30

五 处理DataFrame数据的一些方法

  1. at属性
    指定修改DataFrame数据中的某一个数据
df = pd.DataFrame({'id':[1,2,3],'name':['张三','李四','王五'],'age':[28,25,30]})
df.at[2,'name'] = '王六'
df.at[3,'name'] = '王七'
print(df)

运行效果如下:

id   name  age
0  1.0  张三  28.0
1  2.0  李四  25.0
2  3.0  王七  30.0
3  NaN  王六   NaN
  1. columns属性
    修改表头名
df.columns = ['A','B','C']
print(df)

运行效果如下:

A   B   C
0  1  张三  28
1  2  李四  25
2  3  王五  30
  1. sort_values方法
    将指定的列作为排序规则,根据这列的大小进行排序。如果指定多列,先排序前面指定的,排序过程种出现相等情况后再按后面指定的排序。
df = pd.DataFrame({'name':['张三','李四','王五','小王','小李','小张'],'score':[60,60,80,80,70,90],'age':[28,25,30,17,19,18]})
# by为需要进行排序的哪些列;inplace=True表示排序操作就地执行;ascending升序
df.sort_values(by=['score', 'age'], inplace=True, ascending=[True, True])
print(df)

运行效果如下:

name  score  age
1   李四     60   25
0   张三     60   28
4   小李     70   19
3   小王     80   17
2   王五     80   30
5   小张     90   18
  1. isnull().any()方法
    查看哪些列存在空值。
df = pd.DataFrame({'id':[1,2,3],'name':['张三','李四',None],'age':[28,25,30]})
print(df.isnull().any())

运行效果如下:

id      False
name     True
age     False
dtype: bool
  1. dropna()方法,fillna方法
df.dropna(inplace=True)	# 清除NaN的行
df.fillna(0)	# 将df全部的NaN填充为0
  1. str.split方法
    使用str.split方法可以DataFrame数据某一个列划分成多列。
df = pd.DataFrame({'id':[1,2,3],'name':['张三:28','李四:25','王五:30']})
# expand=True将返回DataFrame对象;Flase将返回Series对象,每个元素是各列表
df1 = df['name'].str.split(':',expand=True)
df2 = df['name'].str.split(':',expand=False)
print(df1)
print(df2)

运行效果如下:

0   1
0  张三  28
1  李四  25
2  王五  30

0    [张三, 28]
1    [李四, 25]
2    [王五, 30]
Name: name, dtype: object
  1. join方法
    使用join方法合并两个或多个DataFrame数据。
    (1)默认按索引index合并
df = pd.DataFrame({'id':[1,2,3],'name':['张三','李四','王五']})
df1 = pd.DataFrame({'age':[28,25,30]})
df2 = pd.DataFrame({'score':[60,70,80]})
df3 = df.join(df1)  # 单个合并
df4 = df.join([df1,df2])    # 多个合并
print(df3)
print(df4)

运行效果如下:

id  name  age
0   1   张三   28
1   2   李四   25
2   3   王五   30
   id  name  age  score
0   1   张三   28     60
1   2   李四   25     70
2   3   王五   30     80

(2)若其中一个DataFrame合并的键不在索引上,可使用on参数

df = pd.DataFrame({'id':[1,2,3],'name':['张三','李四','王五']}).set_index('name')
print(df)
df1 = pd.DataFrame({'name':['张三','李四','王五'],'age':[28,25,30]})
df2 = df1.join(df,on='name',how='outer')
print(df2)

运行效果如下:

id
name    
张三     1
李四     2
王五     3
   name  age  id
0   张三   28   1
1   李四   25   2
2   王五   30   3
  1. merge方法
    两个DataFrame合并的键都不在索引上,使用merge方法。
df = pd.DataFrame({'id':[1,2,3],'name':['张三','李四','王五']})
df1 = pd.DataFrame({'name':['张三','李四','王五'],'age':[28,25,30]})
df2 = df.merge(df1,on='name',how='left')
print(df2)

运行效果如下:

id name  age
0   1   张三   28
1   2   李四   25
2   3   王五   30

PS:若有错误,望读者私信给予纠正!本文后续可能还会给予补充和修改。