文章来源:towardsdatascience
作者:B.Chen
翻译\编辑:Python大数据分析
pandas是python中常用的数据分析库,出现频率非常高,而且pandas功能之多让人咋舌,即使pandas老手也没法保证能高效使用pandas做数据分析。
这篇文章目的梳理几个高效实用的pandas小技巧,供大家参考。
pandas中的read_clipboard()
方法非常神奇,可以把剪切板中的数据变成dataframe格式,也就是说直接在excel中复制表格,可以快速转化为dataframe。
以下面这个excel数据表为例,全部选中,按ctrl+c复制:
然后在python中执行pd.read_clipboard()
,就能得到一模一样的dataframe数据表:
pd.read_clipboard()
这功能对经常在excel和python中切换的分析师来说简直是福音,excel中的数据能一键转化为pandas可读格式。
数据分析过程可能会需要筛选数据列,比如只需要数值列,以经典的泰坦尼克数据集为例:
import seaborn as sns
# 导出泰坦尼克数据集
df = sns.load_dataset('titanic')
df.head()
查看该数据集各列的数据类型:
df.dtypes
可以看到各列的数据类型不太一样,有int、object、float、bool
等。
如果说我只要需要数值列,也就是数据类型为int、float
的列,可以通过select_dtypes
方法实现:
df.select_dtypes(include='number').head()
选择除数据类型为int
外其他的列,注意这里的参数是exclude
:
df.select_dtypes(exclude='int').head()
也可以选择多种数据类型:
df.select_dtypes(include=['int', 'datetime', 'object']).head()
在pandas中,有两种方法可以将字符串改为数值:
astype()
方法
to_numeric()
方法
先创建一个样本dataframe,看看这两种方法有什么不同。
import pandas as pd
df = pd.DataFrame({ 'product': ['A','B','C','D'],
'price': ['10','20','30','40'],
'sales': ['20','-','60','-']
})
df
product列是字符串类型,price、sales列虽然内容有数字,但它们的数据类型也是字符串。
值得注意的是,price列都是数字,sales列有数字,但空值用-
代替了。
df.dtypes
下面我们用astype()
方法将price列的数据类型改为int
:
df['price'] = df['price'].astype(int)
# 或者用另一种方式
df = df.astype({'price': 'int'})
但如果你同样用astype()
方法更改sales列的话就会出现报错:
df['sales'] = df['sales'].astype(int)
原因是sales列里面的内容除了数字外还有-
,它是字符串,没办法转化为int
。
而to_numeric()
方法却可以解决这一问题,只需要设置参数errors='coerce'
。
df['sales'] = pd.to_numeric(df['sales'], errors='coerce')
df
现在sale列中的-
已经被替换成了NaN
,它的数据类型也变成了float
。
df.dtypes
有一种比较通用的检测缺失值的方法是info()
,它可以统计每列非缺失值的数量。
还是用泰坦尼克数据集:
import seaborn as sns
# 导出泰坦尼克数据集
df = sns.load_dataset('titanic')
df.info()
标红色地方是有缺失值的列,并且给出了非缺失值的数量,你可以计算出该列有多少缺失值。
这样看可能不够直观,那可以用df.isnull().sum()
方法很清楚地得到每列有多少缺失值:
df.isnull().sum()
df.isnull().sum().sum()
则能够返回该数据集总共有多少缺失值:
df.isnull().sum().sum()
还可以看缺失值在该列的占比是多少,用df.isna().mean()
方法:
df.isna().mean()
注意:这里isnull()
和isna()
使用效果一样。
那如何处理缺失值呢?
两种方式:删除和替换。
删除包含缺失值的行:
df.dropna(axis = 0)
删除包含缺失值的列:
df.dropna(axis = 1)
如果一列里缺失值超过10%,则删除该列:
df.dropna(thresh=len(df)*0.9, axis=1)
用一个标量替换缺失值:
df.fillna(value=10)
用上一行对应位置的值替换缺失值:
df.fillna(axis=0, method='ffill')
用前一列对应位置的值替换缺失值:
df.fillna(axis=1, method='ffill')
用下一行对应位置的值替换缺失值:
df.fillna(axis=0, method='bfill')
用后一列对应位置的值替换缺失值:
df.fillna(axis=1, method='bfill')
使用某一列的平均值替换缺失值:
df['Age'].fillna(value=df['Age'].mean(), inplace=True)
当然你还可以用最大最小值、分位数值等来替换缺失值。
在数据准备过程中,常常会组合或者转换现有特征以创建一个新的特征,其中将连续数据离散化是非常重要的特征转化方式,也就是将数值变成类别特征。
同样以泰坦尼克数据集为例,里面有一列是年龄特征age
:
import seaborn as sns
# 导出泰坦尼克数据集
df = sns.load_dataset('titanic')
df['age'].head()
年龄是一段连续值,如果我们想对它进行分组变成分类特征,比如(<=12,儿童)、(<=18,青少年)、(<=60,成人)、(>60,老人),可以用cut
方法实现:
import sys
df['ageGroup']=pd.cut(
df['age'],
bins=[0, 13, 19, 61, sys.maxsize],
labels=['儿童', '青少年', '成人', '老人']
)
df.head()
注意:这里的sys.maxsize是指可以存储的最大值。
可以看到新增了一列ageGroup,用以展示年龄分组:
df['ageGroup'].head()
有时候数据集可能分布在多个excel或者csv文件中,但需要把它读取到一个DataFrame中,这样的需求该如何实现?
做法是分别读取这些文件,然后将多个dataframe组合到一起,变成一个dataframe。
这里使用内置的glob模块,来获取文件路径,简洁且更有效率。
在上图中,glob()
在指定目录中查找所有以“ data_row_”开头的CSV文件。
glob()
以任意顺序返回文件名,这就是为什么使用sort()
函数对列表进行排序的原因。
「行合并」
假设数据集按行分布在2个文件中,分别是data_row_1.csv和data_row_2.csv
用以下方法可以逐行合并:
files = sorted(glob('data/data_row_*.csv'))
pd.concat((pd.read_csv(file) for file in files), ignore_index=True)
sorted(glob('data/data_row_*.csv'))
返回文件名,然后逐个读取,并且使用concat()
方法进行合并,得到结果:
「列合并」
假设数据集按列分布在2个文件中,分别是data_row_1.csv和data_row_2.csv
用以下方法可以逐列合并:
files = sorted(glob('data/data_col_*.csv'))
pd.concat((pd.read_csv(file) for file in files), axis=1)
sorted(glob('data/data_row_*.csv'))
返回文件名,然后逐个读取,并且使用concat()
方法进行列合并(注意这里axis=1),得到结果:
本文就到这里,pandas还有很多让人惊喜的小技巧,大家有兴趣也可以在评论区说说你的使用心得。
往期精彩回顾
适合初学者入门人工智能的路线及资料下载机器学习及深度学习笔记等资料打印机器学习在线手册深度学习笔记专辑《统计学习方法》的代码复现专辑
AI基础下载机器学习的数学基础专辑获取一折本站知识星球优惠券,复制链接直接打开:https://t.zsxq.com/662nyZF本站qq群1003271085。加入微信群请扫码进群(如果是博士或者准备读博士请说明):