Pandas 常用操作
Pandas 是 Python 语言的一个用于数据分析的扩展程序库。
官网地址:https://pandas.pydata.org/docs/user_guide/index.html
1. 安装 pandas
如果你使用的是 Anaconda
那么你已经有了 Pandas
了,直接使用即可
pip install pandas
2. pandas 常用操作
本文档中行、列分别使用 row
和 col
表示。
- 行标签依次是 row1、row2、...
- 列标签依次是 col1、col2、...
设置输出宽度
https://pandas.pydata.org/pandas-docs/stable/user_guide/options.html
pd.set_option('display.width', None)
设置成 None
后,在打印 dataframe 时,pandas 将正确地自动检测宽度。输出的列不再换行,更加美观。
dtypes 查看每列的数据类型
https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.dtypes.html
print(df.dtypes)
astype() 更改类型
https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.astype.html
df['col1'] = df['col1'].astype(str)
df.astype({'col2': 'int32'})
info() 打印简明摘要
https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.info.html
df.info(verbose=True)
此方法打印有关 DataFrame 的信息,包括索引 dtype 和列、以及非空值和内存使用情况。
empty 判断是否为空
https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.empty.html
if df.empty:
print('df is empty.')
head() 返回前几行
https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.head.html
df.head() # 默认返回前5行
df.head(3) # 指定返回前3行
df.head(-3) # 返回除最后3行之外的所有行,相当于 df[:-3]
tail() 返回后几行
https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.tail.html
df.tail() # 默认返回后5行
df.tail(3) # 指定返回后3行
df.tail(-3) # 返回除最前3行之外的所有行,相当于 df[3:]
at[]/iat[] 访问单个值
https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.at.html
df.at['row3', 'col1'] # at 使用行/列标签访问单个值
df.iat[3, 1] # iat 使用行/列整数位置访问单个值
loc[] 按照标签访问指定行/列
https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.loc.html
通过标签或布尔数组访问一组行和列。.loc[]
主要是基于标签的,但也可以与布尔数组一起使用。
df.loc['row1'] # 单标签。返回第1行,类型是 Series
df.loc[['row1', 'row2']] # 标签列表。使用 [[]] 返回一个 DataFrame
df.loc['row3', 'col1'] # 通过行/列标签访问单个值,与 at 一样
df.loc['row1':'row3', 'col1'] # 切片两头都包含。此处返回第1到3行和第1列组成的 DataFrame
df.loc[[False, False, True]] # 返回第3行的 DataFrame
df.loc[df['col1'] > 6] # 返回第1列值大于6的 DataFrame
df.loc['row1'] = 10 # 为整行设置值,此处是将第1行的值全部设置为10
df.loc[:, 'col2'] = 30 # 为整列设置值,此处是将第2列的值全部设置为30
df.loc[df['col3'] > 35] = 0 # 为满足条件的行设置值
iloc[] 按照数字访问指定行/列
https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.iloc.html
纯粹基于整数位置的索引,用于按位置进行选择。.iloc[]
主要基于整数位置,但也可以与布尔数组一起使用。
df.iloc[0] # 返回第1行,类型是 Series
df.iloc[[0]] # 返回第1行的 DataFrame
df.iloc[:3] # 返回前3行的 DataFrame
df.iloc[[True, False, True]] # 返回第1行和第3行的 DataFrame
df.iloc[0, 1] # 通过行/列整数位置访问单个值,与 iat 一样
df.iloc[[0, 2], [1, 3]] # 返回第1行和第3行与第2列和第4列组成的 DataFrame
df.iloc[1:3, 0:3] # 切片两头都包含。此处返回第2到4行和第1列到第4列组成的 DataFrame
insert() 插入新列
https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.insert.html
在指定位置将列插入 DataFrame。
df.insert(1, 'col5', [99, 99]) # 此处为插入名为 col5 的新列到第2列的位置上,值的长度需要与行数对应
iteritems()/iterrows()/itertuples() 遍历
https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.itertuples.html
还有一个 items()
方法,它是 iteritems()
的别名
常用 itertuples()
进行遍历
for label, content in df.iteritems(): pass # label 是列名;content 是列内容,Series 类型
for index, content in df.iterrows(): pass # index 是行名;content 是行内容,Series 类型
for row in df.itertuples(): pass # 以命名元组的形式迭代 DataFrame 行。row 是 namedtuple 类型
pop() 获取并删除列
https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.pop.html
df.pop('col2') # 返回第2列,并且会删除它
apply() 对行或列应用函数
https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.apply.html
传递给函数的对象是 Series 对象
df.apply(np.sum, axis=0) # 对每列进行求和
df.apply(np.sum, axis=1) # 对每行进行求和
axis
参数取值:
- 0:将函数应用于每一列。
- 1:将函数应用于每一行。
applymap() 对每个元素应用函数
https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.applymap.html
df.applymap(lambda x: x**2)
agg()/aggregate() 聚合操作
https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.agg.html
agg 是 aggregate 的别名,两者功能一样
df.agg(['sum', 'min']) # 对每列进行求和和求最小值
df.agg({'col1' : ['sum', 'min'], 'col2' : ['min', 'max']}) # 指定列指定聚合操作
df.agg('mean', axis=1) # 对每行进行求平均值
groupby() 分组
https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.groupby.html
df = df.groupby(['col1']).sum() # 基于第1列的值进行分组,并对分组后的其他列求和
df = df.groupby(['col1', 'col2']).agg({'col3': lambda x: len(x.unique())}) # 求去重个数
df = df.groupby(['col1', 'col2']).col3.nunique() # 求去重个数
df = df.groupby(['col1', 'col2']).agg({'col3': count, 'col3': lambda x: len(x.unique()), 'col4': sum})
drop() 删除指定行或列
https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.drop.html
df.drop(['col2', 'col3'], axis=1) # 删除第2列和第3列
df.drop(columns=['col2', 'col3']) # 同上
df.drop([0, 1]) # 删除第1行和第2行
df.drop(index='i1', columns='col1') # 删除i1索引的所有行,以及第1列
drop_duplicates() 去重
https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.drop_duplicates.html
- 默认情况下,它会根据所有列删除重复的行,默认保留第一个。
- 要删除特定列上的重复项,请使用
subset
。 - 要删除重复项并保留最后一次出现,请使用
keep
。
df.drop_duplicates()
df.drop_duplicates(subset=['col1']) # 按照第1列删除重复项
df.drop_duplicates(keep='last') # 保留最后一个重复项
rename() 更改列名
https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.rename.html
df.rename(columns={'col1': 'A', 'col2': 'B'}) # 更改列名
df.rename(index={0: 'x', 1: 'y', 2: 'z'}) # 更改索引名
reset_index() 重置索引
https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.reset_index.html
重置 DataFrame 的索引,并使用默认索引。如果 DataFrame 有 MultiIndex,则此方法可以删除一个或多个级别。
df.reset_index()
df.reset_index(drop=True) # 使用 drop 参数来避免将旧索引添加为列
set_index() 设置索引
https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.set_index.html
使用现有列设置 DataFrame 索引。
使用一个或多个现有列或数组(长度正确)设置 DataFrame 索引(行标签)。索引可以替换现有索引或对其进行扩展。
df.set_index('col1')
df.set_index(['col1', 'col2'])
操作 NA/NaN
dropna()
: 删除 NA/NaN 值。fillna()
: 使用指定的方法填充 NA/NaN 值。isna()/isnull()
: 检测是否是 NA/NaN 值。notna()/notnull ()
: 检测是否不是 NA/NaN 值。
df.dropna() # 去掉包含 NaN 的所有行
df.dropna(axis=1) # 去掉包含 NaN 的所有列
df.dropna(subset=['col1', 'col2']) # 去掉第1列和第2列中包含 NaN 的所有行
df.fillna(0) # 填充为 0
df.fillna(value={'col1': 0, 'col2': 1}) # 指定每列填充的数值
df.fillna(df2) # 使用 df2 来填充
df.isna() # 返回一个布尔值相同大小的对象,指示值是否为 NA
检测单个值是否为 NA/NaN
https://pandas.pydata.org/docs/reference/api/pandas.isna.html#pandas.isna
注意这里是 pandas 的顶层函数,不是 DataFrame 的函数
pd.isna(cell_value)
pd.notna(cell_value)
sort_values() 排序
https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.sort_values.html
df = df.sort_values(['col1', 'col2'], ascending=False)
concat() 拼接/扩展
https://pandas.pydata.org/docs/reference/api/pandas.concat.html#pandas.concat
append()
已弃用,使用 concat()
代替
pd.concat([df1, df2]) # 纵向扩展,拼接成新行
pd.concat([df1, df4], axis=1) # 横向扩展,拼接成新列
merge() 合并
https://pandas.pydata.org/docs/reference/api/pandas.merge.html
df = pd.merge(df1, df2, on=['col1', 'col2'])
update() 更新
https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.update.html
df.update(new_df)
read_csv() 读取 csv 文件
https://pandas.pydata.org/docs/reference/api/pandas.read_csv.html
df = pd.read_csv(csv_path)
to_csv() 保存为 csv 文件
https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.to_csv.html
df.to_csv('test.csv', header=True, index=False, encoding='utf_8_sig') # 此编码可正常显示中文
to_dict() 转为字典
https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.to_dict.html
df.to_dict('records') # 返回样式示例:[{'col1': 1, 'col2': 0.5}, {'col1': 2, 'col2': 0.75}]
一次创建多个列
https://stackoverflow.com/questions/23586510/return-multiple-columns-from-pandas-apply
df[['col3', 'col4', 'col5']] = df.apply(func, axis=1, result_type='expand')
上面的 func
函数相应的需要返回3个元素的元组