Pandas基础
Pandas教程
基础功能
Excel对象
- pd.ExcelFile
- 属性
sheet_names:返回 Excel 文件中所有工作表的名称列表book:与 openpyxl 或 xlrd 等 Excel 处理引擎交互,允许用户访问 Excel 文件的底层对象book.worksheets[0].max_row:返回第一个工作表的最大行数
- 方法
parse:读取指定工作表的数据并返回为 Pandas DataFrame。可以指定参数,如header、skiprows、usecols等,以控制读取行为close:关闭excel文件,释放资源
- 属性
- pd.ExcelWriter
- 参数
mode:默认值为ww: 写入模式,若文件存在则覆盖a: 追加模式,向现有文件中添加数据
if_sheet_exists:默认值为errorerror: 抛出错误,默认行为new: 创建一个新的工作表replace: 替换已存在的工作表overlay:在已存在的工作表基础上追加
- 参数
将多个 DataFrame 写入同一个工作表中的不同区域
1 | data1 = { |
追加数据至已存在的工作表
1 | with pd.ExcelWriter( |
函数应用
pipe()管道方法
1 | # 传入位置参数或关键字参数 |
函数 fun 的第一个参数不是数据本身,可采用一元组来传递
1 | # 数据是第二个参数 |
map()方法
apply()方法
result_type=None:{‘expand’, ‘reduce’, ‘broadcast’, None}, 默认 None,仅在 axis=1 (columns) 时都起作用:expand: 类似列表的结果将转换为列reduce: 如果可能,返回一个序列,而不是像列表一样展开结果。这与expand相反broadcast: 结果将被广播到数据帧的原始形状,原始索引和列将被保留None:默认行为(None)取决于应用函数的返回值:类似列表的结果将作为一Series 结果返回。但是,如果 apply 函数返回一个 Series,这些序列将展开为列
1 | s = pd.Series([20, 21, 12], index=["London", "New York", "Helsinki"]) |
agg()方法
- 聚合滚动窗口
Rolling.agg
1 | df = pd.DataFrame({"A": [1, 2, 3], "B": [4, 5, 6], "C": [7, 8, 9]}) |
transform方法
题目:需要增加一个名为「所属组别的值」的列,对应值为当前组别下「值」的列表
1 | from io import StringIO |
解法
1 | foo = df.groupby('组别').值.transform(lambda x: [x.to_list()] * len(x)) |
多级索引
性能问题:传入元组列表或单个元组或返回前二者的函数时,需要先进行索引排序以避免性能警告
1 | df.set_index(["team","name"],inplace=True) |
特殊写法:可以对多层的元素在交叉组合后进行索引,但同时需要指定loc 索引器的列,全选则用
:表示
1 | df.set_index(["team","Q1"],inplace=True) |
题目:sample()函数中主要的参数为n、axis、frac、replace 和weights,前3 个分别指抽样数量、抽样的方向(0 为行、1 为列)和抽样比例(如0.3 表示从总体中抽出30%的样本)。replace 和weights分别指是否放回和每个样本抽样的相对概率,replace 为True 表示有放回抽样
1 | # 使用iloc和np.random.choice实现sample函数 |
数据合并
时序数据合并
pd.merge_asof:类似于left-join
direction- 默认
backward向后,搜索选择右数据中on键小于或等于左键的最后一行,比它小的里边最大的 forward向前,搜索选择右侧数据中的第一行,其on键大于或等于左侧的键,比它大的里边最大的nearest最近,搜索选择右侧数据中的行,该行的on键在绝对距离上最接近左侧的键,和它差值绝对值最小的
- 默认
allow_exact_matches- 如为 True(默认), 允许与相同的值匹配(即小于或等于/大于或等于)
- 如为 False, 不匹配相同的值(即严格要求小于/大于,就是不能等于)
1 | left = pd.DataFrame({"a": [1, 5, 10], "left_val": ["a", "b", "c"]}) |
逐元素合并
df.combine_first
1 | df1 = pd.DataFrame({'A': [None, 0], 'B': [4, None]}) |
df.update
使用
pd.Series更新,必须设置其name属性对应列
1 | df = pd.DataFrame({'A': ['a', 'b', 'c'], |
其他包含NaN,则相应的值不会在原始数据帧中更新
1 | df = pd.DataFrame({'A': [1, 2, 3], |
数据对比
df.compare
1 | df = pd.DataFrame( |
df.align
1 | df1 = pd.DataFrame([[1,2,3,4], [6,7,8,9]], |
数据清洗
数据替换
replace
1 | ser = pd.Series(range(5)) |
正则替换
1 | d = {'a': list(range(4)), |
case_when
1 | # caselist为元祖嵌套的列表,元祖内为(判定条件产生的布尔序列,替换值) |
分组聚合
gb.apply
- 单列应用
pd.Series
1 | # Series的索引会添加到分组的索引中 |
- 单列/多列应用
pd.DataFrame
1 | # 单列/多列效果相同 |
- 多列应用
pd.Series
1 | # Series的索引会成为columns |
pd.Grouper() 分组器
closed (
'left'或'right'):
在时间序列分组时,指定区间是左闭还是右闭。如果未指定freq参数,此参数无效。label (
'left'或'right'):
指定区间的标记方式,'right'表示右边界,'left'表示左边界。仅在freq参数指定时有效。origin (
Timestamp或str, 默认为'start_day'):
调整分组的起点时间戳。可选值包括:'epoch':从1970-01-01开始'start':时间序列的第一个值'start_day':时间序列的第一个午夜'end':时间序列的最后一个值'end_day':时间序列的最后一天的午夜
数据分箱
x:需要分箱的一维数据(如Series、ndarray)。bins:- 如果是整数,表示将数据分成指定数量的等宽区间 -> 类似np.linspace形成等差区间
- 如果是序列,表示自定义的区间边界。
right:是否为右闭区间,默认为True(区间形如(a, b])。labels:- 指定每个区间的标签(如
['Low', 'Medium', 'High'])。 - 如果为
False,则返回区间编号而不是标签。
- 指定每个区间的标签(如
retbins:是否返回实际使用的分箱边界,默认False。precision:区间端点的小数精度,默认为 3。include_lowest:是否将第一个区间的左端点包含在内(仅在right=True时生效)。duplicates:- 如果分箱边界有重复值,默认抛出异常。
- 可设置为
'drop'忽略重复边界。
1 | # 语法 |
x(必选)- 一维数据,如
list、ndarray、Series等。 - 是需要分箱的数据。
- 一维数据,如
q(必选)- 分位数的数量或具体的分位点。
- 如果是整数,则表示分成
q个等分位区间(例如,q=4分成四分位数)。 - 如果是列表,则表示指定分位点(如
[0, 0.25, 0.5, 0.75, 1])。
labels(可选,默认为None)- 为每个区间指定标签。
- 可以是布尔值、字符串列表或整数列表:
- 如果为
False,返回区间编号(从 0 开始)。 - 如果为
None,返回默认的区间(如(a, b]格式)。 - 如果提供自定义标签,数量必须与区间数量一致。
- 如果为
retbins(可选,默认为False)- 是否返回实际使用的分箱边界。
- 如果为
True,则返回分箱结果和分箱边界。
precision(可选,默认为3)- 分箱边界的精度,即小数点后的位数。
duplicates(可选,默认为'raise')- 如果分箱边界中有重复值的处理方式:
'raise':抛出异常。'drop':忽略重复边界。
- 如果分箱边界中有重复值的处理方式:
1 | # 语法 |
重塑透视
数据透视
df.pivot
- index:新 df 的索引列,用于分组,如果为None,则使用现有索引
- columns:新 df 的列,如果透视后有重复值会报错
- values:用于填充 df 的列。 如果未指定,将使用所有剩余的列,并且结果将具有按层次结构索引的列
1 | df = pd.DataFrame({'foo': ['one', 'one', 'one', 'two', 'two', |
df.pivot_table
- values: 要聚合的列或者多个列
- index: 在数据透视表索引上进行分组的键
- columns: 在数据透视表列上进行分组的键
- aggfunc: 用于聚合的函数, 默认是 numpy.mean
- margins: 给行和列添加一个汇总,默认名字是ALL
- margins_name: 替换默认汇总行和列的名字
1 | df = pd.DataFrame({"A": ["foo", "foo", "foo", "foo", "foo", |
交叉表 crosstab
- index:类数组,在行中按分组的值。
- columns:类数组的值,用于在列中进行分组。
- values:类数组的,可选的,要根据因素汇总的值数组。
- aggfunc:函数,可选,如果未传递任何值数组,则计算频率表。
- rownames:序列,默认为None,必须与传递的行数组数匹配。
- colnames:序列,默认值为None,如果传递,则必须与传递的列数组数匹配。
- margins:布尔值,默认为False,添加行/列边距(小计)
- normalize:布尔值,{‘all’,’index’,’columns’}或{0,1},默认为False。 通过将所有值除以值的总和进行归一化。
1 | # 语法 |
1 | # 实例:A B 两列进行交叉,A有不重复的值1和2,B有3和4。交叉后组成了新的数据,具体的值为对应行列上的组合在原数据中的数量 |
逆透视melt
- id_vars: tuple,list或ndarray(可选),用作标识变量的列。
- value_vars: tuple,列表或ndarray,可选,要取消透视的列。 如果未指定,则使用未设置为id_vars的所有列。
- var_name: scalar,用于“变量”列的名称。 如果为None,则使用frame.columns.name或“variable”。
- value_name: scalar,默认为“ value”,用于“ value”列的名称。
- col_level: int或str,可选,如果列是MultiIndex,则使用此级别来融化。
虚拟变量/哑变量
pd.get_dummies() 是将一个或者多个列的去重值做为新表的列,每个列的值由0和1组成,在原来此位为此列名的值为1,不是的为0,这样就形成了一个由 0 和1 组成的特征矩阵
1 | df = pd.DataFrame({'key': list('bbacab'), 'data1': range(6)}) |
factorize() 因子化值
1 | codes, uniques = pd.factorize(['b', 'b', 'a', 'c', 'b'], sort=True) |

