如何快速驾驭 pandas 库
最近有小伙伴提到,Python 做数据分析的 pandas 库函数和方法实在太多,感觉学习和使用起来思路都非常混乱。之前回复过这个问题,今天把它更系统的整理一下,毕竟这个库是 Python 数据科学生态圈中扮演着极为重要的角色,虽然目前有很多 pandas 库的替代品(如:polars、cuDF等),但是使用方法跟 pandas 可以说是大同小异。
三个核心类
Pandas 库有三个最核心的类,其中最重要的是DataFrame类型,它是学习的重点,如下图所示。
Series:表示一维数据,跟一维数组类似(带标签的数组),每个数据都有自己的索引(标签),可以通过索引访问数据。
DataFrame:表示二维数据,类似于 Excel 电子表格,行和列都有自己的索引(标签),可以通过索引访问行、列、单元格。
Index:表示索引,为Series和DataFrame 提供索引服务,Index有很多的子类型,适用于需要不同类型的索引的场景。
数据分析流程
学习和使用 pandas 重点是DataFrame的应用,我们建议大家按照数据分析的流程来掌握对应的函数和方法,这样做往往会事半功倍。数据分析流程如下图所示,其中蓝色虚线圈中的部分就是可以通过 BI 工具(如:Power BI、Tableau等)或 Python 程序来完成的部分。
数据获取
数据获取也可以称为数据加载,其本质就是创建DataFrame对象,需要掌握以下几个函数:
- 从 CSV 文件加载数据。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| pd.read_csv( filepath, sep, header, encoding, quotechar, usecols, index_col, dtype, converters, nrows, skiprows, parse_dates, date_format, true_values, false_values, na_values, na_filter, on_bad_lines, engine, iterator, chunksize, )
|
- 从 Excel 文件加载数据。
1 2 3 4 5
| pd.read_excel( io, sheet_name, skip_footer, )
|
说明:read_excel函数跟read_csv有很多作用相同的参数,这里就没有赘述了。从 Excel 文件中加载数据时,没有迭代器模式。
- 从数据库或数仓加载数据。
1 2 3 4 5 6 7 8 9
| pd.read_sql( sql, con, parse_dates, index_col, columns, chunksize, dtype, )
|
- 其他创建
DataFrame对象的方式。
1 2
| pd.DataFrame(data=[[95, 87], [66, 78], [92, 89]], index=[1001, 1002, 1003], columns=['Verbal', 'Math']) pd.DataFrame(data={'Verbal': [95, 66, 92], 'Math': [87, 78, 89]}, index=[1001, 1002, 1003])
|
如果要对DataFrame中的数据或索引进行操作,需要掌握下面的运算和方法。
- 查看信息
- 查看前/后 N 行
- 操作列
1 2
| df['column_name'] df.colume_name
|
- 操作行
1 2
| df.loc['row_index'] df.iloc[0]
|
- 操作单元格
1 2
| df.at['row_index', 'column_name'] df.iat[0, 0]
|
- 删除行或列
1 2 3 4 5 6 7
| df.drop( labels, axis, index, columns, inplace, )
|
- 筛选数据
1 2
| df.query(expr) df[bool_index]
|
- 随机抽样
1 2 3 4 5 6
| df.sampe( n, frac, replace, random_state, )
|
- 重置索引
1 2 3 4 5
| df.reset_index( level, drop, inplace, )
|
- 设置索引
1 2 3 4 5 6 7
| df.set_index( keys, drop, append, inplace, verify_integrity, )
|
- 调整索引顺序
1 2 3 4
| df.reindex() df[fancy_index] df.loc[facy_index] df.iloc[fancy_index]
|
- 索引排序
1 2 3 4 5 6 7 8 9
| df.sort_index( axis, level, ascending, inplace, kind, na_position, key, )
|
数据重塑
- 拼接(类似于 SQL 中的 union 操作)
1 2 3 4 5
| pd.concat( objs, axis, ignore_index, )
|
- 合并(类似于 SQL 中的 join 操作)
1 2 3 4 5 6 7 8 9 10 11
| pd.merge( left, right, how, on, left_on, right_on, left_index, right_index, suffixes, )
|
数据清洗
- 缺失值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| df.isna() df.notna()
df.dropna( axis, how, subset, inplace, )
df.fillna( value, method, inplace, )
df.interpolate( method, axis, inplace, )
|
- 重复值
1 2 3 4 5 6 7 8 9 10 11 12 13
| df.duplicated( subset, keep, )
df.drop_duplicates( subset, keep, inplace, )
df.nunique(axis)
|
- 异常值
异常值的处理重点在甄别,可以使用数值判定法、z-score 判定法、孤立森林等方法来进行甄别离群点,然后结合实际业务意义判定是不是异常值。对于异常值的处理,通常是替换或删除,删除可以用之前提到的drop方法删行或者删列。
1 2 3 4 5 6 7
| df.replace( to_replace, value, inplace, regex, )
|
- 预处理
预处理通常在Series对象上对数据进行操作,假设变量s是一个Series对象,具体的操作包括:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| s.dt.year s.dt.quarter s.dt.month s.dt.day s.dt.hour s.dt.minute s.dt.second s.dt.weekday s.dt.to_period(freq) s.dt.floor(freq) s.dt.ceil(freq) s.dt.round(freq) s.dt.strftime(date_format) s.dt.tz_localize(tz) s.dt.tz_convert(tz)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| s.str.lower() s.str.upper() s.str.title()
s.str.split( pat, n, expand, )
s.str.extract( pat, flags, expand, ) s.str.isalpha() s.str.isnumeric() s.str.isalnum() s.str.isspace() s.str.startswith() s.str.endswith()
s.str.match( pat, flags, )
s.str.contains( pat, flags, regex, )
s.str.replace( pat, repl, n, flags, regex, ) s.str.strip() s.str.join(sep)
s.str.cat( others, sep, na_rep, ) s.str.len()
s.str.find( sub, start, end, )
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| s.cat.reorder_categories( new_categories, inplace, )
s.cat.add_categories( new_categories, inplace, )
s.cat.remove_categories( removals, inplace, )
s.cat.remove_unused_categories( inplace, )
s.cat.rename_categories( new_categories, inplace, )
|
1 2 3 4 5 6 7 8
| pd.get_dummies( data, prefix, prefix_sep, dummy_na, columns, drop_first, )
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| pd.cut( x, bins, right, labels, retbins, ordered, ) pd.qcut( x, q, labels, retbins, )
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| s.map(arg) df.map(func)
s.apply( func, convert_type, args, kwargs, )
df.apply( func, axis, result_type, args, kwargs, ) s.transform(func) df.transform(func)
|
数据透视
- 描述性统计信息
1 2 3 4 5 6 7 8 9
| s.mean() s.median() s.mode() s.max() s.min() s.var(ddof) s.std(ddof) s.skew() s.kurt()
|
- 相关性分析
1 2
| df.cov() df.corr(method)
|
- 排序和头部值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| s.sort_values( asending, inplace, kind, na_position, key, )
df.sort_values( by, ascending, inplace, kind, na_position, key, )
s.nlargest( n, keep, )
df.nlargest( n, columns, keep, )
s.nsmallest( n, keep, )
df.nsmallest( n, columns, keep, )
|
- 分组聚合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| df.groupby( by, level, as_index, sort, observed, ).aggregate( func, args, kwargs, ) df.pivot( index, columns, values, ) df.melt( id_vars, value_vars, var_name, value_name, )
|
- 透视表
1 2 3 4 5 6 7 8 9 10 11
| pd.pivot_table( data, values, index, columns, aggfunc, fill_value, margins, margins_name, observed )
|
- 交叉表
1 2 3 4 5 6 7 8
| pd.crosstab( index, columns, values, aggfunc, margins, margins_name, )
|
数据呈现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| df.plot( figsize, kind, ax, x, y, title, grid, legend, xticks, yticks, xlim, ylim, xlabel, ylabel, rot, fontsize, colormap, stacked, colorbar, )
|
plot方法最重要的参数是kind,它可以控制图表的类型,具体如下所示:
- 折线图:
kind='line'
- 散点图:
kind='scatter'
- 柱状图:
kind='bar'
- 条状图(水平柱状图):
kind='barh'
- 饼状图:
kind='pie'
- 直方图:
kind='hist'
- 箱线图:
kind='box'
- 面积图:
kind='area'
- 核密度估计图:
kind='kde'
总结
大家可以找一个数据集按照上面讲解的流程把这些最常用的类型、函数和方法过一遍,是不是印象就深刻一点了。更详细的内容还是推荐阅读我的专栏《基于Python的数据分析》或者观看B站上的视频《Python数据分析三剑客》。