原题 | 10 Python Pandas tricks that make your work more efficientpython
做者 | Shiu-Tang Li算法
原文 | towardsdatascience.com/10-python-p…shell
译者 | kbsc13("算法猿的成长"公众号做者)微信
声明 | 翻译是出于交流学习的目的,欢迎转载,但请保留本文出于,请勿用做商业或者非法用途多线程
Pandas 是一个普遍应用于数据分析等领域的 Python 库。关于它的教程有不少,但这里会一些比较冷门可是很是有用的技巧。app
这是一个你们都应该知道的函数,由于它就是读取 csv 文件的方法。函数
但若是须要读取数据量很大的时候,能够添加一个参数--nrows=5
,来先加载少许数据,这能够避免使用错误的分隔符,由于并非全部的都采用逗号分隔,而后再加载整个数据集。学习
Ps. 在 Linux 的终端,能够采用 head
命令来查看文件的前 5 行数据,命令示例以下所示:编码
head -n 5 data.txt
复制代码
加载数据后,能够经过方法df.columns.tolist()
获取全部的列名字,再采用参数usecols=['c1','c2',...]
来读取真正须要的列。若是想读取速度更快而且知道一些列的数据类型,可使用参数 dtype={'c1':str, 'c2':int,...}
,使用这个参数的另外一个好处是对于包含不一样类型的列,好比同时包含字符串和整型的列,这个参数能够指定该列就是字符串或者整型的类型,避免在采用该列做为键进行融合不一样表的时候出现错误。spa
若是必须用 Python 进行数据预处理,采用这个方法能够节省一些时间。在读取表后,默认数据类型能够能是 bool, int64, float64, object, category, timedelta64, datetime64
,首先能够用下面的方法来查看分布状况和知道 dataframe
中包含哪些数据类型:
df.dtypes.value_counts()
接着使用下面的方法来选择特定类型的数据,好比说数字特征:
df.select_dtypes(include=['float64', 'int64'])
这个方法很重要,首先先看看下面这个例子:
import pandas as pd
df1 = pd.DataFrame({ 'a':[0,0,0], 'b': [1,1,1]})
df2 = df1
df2['a'] = df2['a'] + 1
df1.head()
复制代码
运行上述代码后,会发现df1
的数值被改变了,这是由于 df2=df1
这段代码并非对 df1
进行拷贝,而后赋给 df2
,而是设置了一个指向 df1
的指针。 所以任何对 df2
的改变都会改变 df1
,若是要修改这个问题,能够采用下面的代码:
df2 = df1.copy()
复制代码
或者
from copy import deepcopy
df2 = deepcopy(df1)
复制代码
这是一个很是酷的命令,能够用于作简单的数据转化操做。首先须要定义一个字典,它的键是旧数值,而其值是新的数值,以下所示:
level_map = {1: 'high', 2: 'medium', 3: 'low'}
df['c_level'] = df['c'].map(level_map)
复制代码
还有一些例子:
若是咱们想建立一个新的采用其余列做为输入的列,apply
方法是一个很是有用的方法:
def rule(x, y):
if x == 'high' and y > 10:
return 1
else:
return 0
df = pd.DataFrame({ 'c1':[ 'high' ,'high', 'low', 'low'], 'c2': [0, 23, 17, 4]})
df['new'] = df.apply(lambda x: rule(x['c1'], x['c2']), axis = 1)
df.head()
复制代码
上面这段代码咱们先定义了一个两个输入参数的方法,而后采用apply
方法将其应用到 df
的两列 c1, c2
。
apply
的问题是有时候速度太慢了。若是是但愿计算 c1
和 c2
两列的最大值,能够这么写:
df['maximum'] = df.apply(lambda x: max(x['c1'], x['c2']), axis = 1)
复制代码
但你会发现比下面这段代码要慢不少:
df['maximum'] = df[['c1','c2']].max(axis=1)
复制代码
要点:若是能够采用其余内置函数实现的工做,就不要采用apply
方法啦。好比,想对列c
的数值进行取舍为整数值,能够采用方法 round(df['c'], o)
或者 df['c'].round(o)
,而不是使用apply
方法的代码:df.apply(lambda x: round(x['c'], 0), axis=1)
这个方法用于检查数值的分布状况。好比,你想知道c
列的每一个惟一数值出现的频繁次数和可能的数值,能够以下所示:
df['c'].value_counts()
复制代码
这里还有一些有趣的技巧或者参数:
df['c'].value_counts().reset_index()
:若是想对这个统计转换为一个 dataframe
并对其进行操做df['c'].value_counts().reset_index().sort_values(by='index')
或者是 df['c'].value_counts().sort_index()
: 实现根据列的每一个取值对统计表进行排序当构建模型的时候,咱们但愿能够删除掉带有太多缺失值的行,或者都是缺失值的行。这能够经过采用.isnull()
和 .sum()
来计算特定列的缺失值数量:
import pandas as pd
import numpy as np
df = pd.DataFrame({ 'id': [1,2,3], 'c1':[0,0,np.nan], 'c2': [np.nan,1,1]})
df = df[['id', 'c1', 'c2']]
df['num_nulls'] = df[['c1', 'c2']].isnull().sum(axis=1)
df.head()
复制代码
在 SQL 中这个操做能够经过SELECT * FROM … WHERE ID in (‘A001’, ‘C022’, …)
来获取特定 IDs 的记录。而在 pandas 中,能够以下所示:
df_filter = df['ID'].isin(['A001','C022',...])
df[df_filter]
复制代码
假设有一个都是数值类型的列,而后但愿对这些数值划分红几个组,好比前 5% 是第一组,5-20%是第二组,20%-50%是第三组,最后的50%是第四组。这能够采用.cut
方法,但这有另一个选择:
import numpy as np
cut_points = [np.percentile(df['c'], i) for i in [50, 80, 95]]
df['group'] = 1
for i in range(3):
df['group'] = df['group'] + (df['c'] < cut_points[i])
# or <= cut_points[i]
复制代码
这个方法的速度很是快。
最后是一个很是经常使用的方法,保存为 csv
文件。这里也有两个小技巧:
第一个就是print(df[:5].to_csv())
,这段代码能够打印前5行,而且也是会保存到文件的数据。
另外一个技巧是处理混合了整数和缺失值的状况。当某一列同时有缺失值和整数,其数据类型是 float
类型而不是 int
类型。因此在导出该表的时候,能够添加参数float_format='%.of'
来将 float
类型转换为整数。若是只是想获得整数,那么能够去掉这段代码中的 .o
欢迎关注个人微信公众号--算法猿的成长,或者扫描下方的二维码,你们一块儿交流,学习和进步!
推荐阅读: