本节前言

数据变换涵盖滞后 / 差分、累积运算、线性代数、算术运算、比较运算与合并对比。它们为特征工程与探索性分析提供基础能力。

1. shift()

将数据沿指定轴移动。

s = pd.Series([1, 2, 3, 4])
s.shift(1)
# 0    NaN
# 1    1.0
# 2    2.0
# 3    3.0
 
s.shift(-1)
# 0    2.0
# 1    3.0
# 2    4.0
# 3    NaN
 
# 按时间频率移动
s_time = pd.Series(
    [1, 2, 3],
    index=pd.to_datetime(['2024-01-01', '2024-01-02', '2024-01-03'])
)
s_time.shift(1, freq='D')
参数说明
periods移动的步数(正数向后,负数向前)
freq时间频率移动(可选)
axis移动方向
fill_value移动后的填充值

2. diff()

计算一阶或 n 阶差分。

s = pd.Series([1, 3, 6, 10])
s.diff()
# 0    NaN
# 1    2.0
# 2    3.0
# 3    4.0
 
s.diff(2)     # 二阶差分
s.diff(periods=1, axis=1)   # DataFrame 列方向差分

3. pct_change()

计算百分比变化率。

s = pd.Series([100, 110, 121])
s.pct_change()
# 0         NaN
# 1    0.100000
# 2    0.100000
 
# 多期百分比
s.pct_change(periods=2)
 
# 自定义填充
s.pct_change(fill_method=None)   # pandas 2.x 默认无填充
方法计算公式用途
diff()绝对变化
pct_change()相对变化率

4. 累积运算

cumsum() / cumprod() / cummin() / cummax()

s = pd.Series([1, 2, 3, 4])
 
s.cumsum()    # 1, 3, 6, 10
s.cumprod()   # 1, 2, 6, 24
s.cummin()    # 1, 1, 1, 1
s.cummax()    # 1, 2, 3, 4
 
# DataFrame 按列累积
df.cumsum(axis=0)
df.cumprod(axis=1)
方法说明
cumsum()累积和
cumprod()累积积
cummin()累积最小值
cummax()累积最大值

缺失值行为

累积运算默认跳过 NaN(skipna=True),如遇 NaN 则保留 NaN 直到下一个有效值。

5. rank()

排名运算(与 6.5 节 rank() 相同)。

s = pd.Series([3, 1, 2, 4])
s.rank()
# 0    3.0
# 1    1.0
# 2    2.0
# 3    4.0

详细说明

排名参数(method、pct、na_option 等)见 6.5 排序与排名。此处大纲单独列出,强调其作为数据变换的一种形式。

6. dot()

矩阵点积(向量内积、矩阵乘法)。

df1 = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})
df2 = pd.DataFrame({'X': [5, 6], 'Y': [7, 8]})
 
df1.dot(df2)
 
s = pd.Series([1, 2])
s.dot(s)   # 5
 
# DataFrame 与 Series
df1.dot(pd.Series([1, 1]))

维度要求

两个对象的维度必须匹配:。

7. transpose() / T

转置 DataFrame(行列互换)。

df = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})
 
df.transpose()
#    0  1
# A  1  2
# B  3  4
 
df.T    # 等价,推荐简写

transpose 相关

转置后索引与列互换。也可用 df.swapaxes(0, 1) 实现。

8. add_prefix() / add_suffix()

为列名添加前缀 / 后缀。

df = pd.DataFrame({'A': [1], 'B': [2]})
 
df.add_prefix('col_')
#    col_A  col_B
# 0      1      2
 
df.add_suffix('_v1')
#    A_v1  B_v1
# 0     1     2

9. 算术运算

基础算术:add / sub / mul / div 等

方法运算符说明
add()+加法
sub()-减法
mul()*乘法
div()/除法
truediv()/真除法
floordiv()//整除
mod()%取模
pow()**幂
df1 = pd.DataFrame({'A': [1, 2]})
df2 = pd.DataFrame({'A': [10, 20]})
 
df1.add(df2)
#     A
# 0  11
# 1  22
 
df1.add(100)               # 标量广播
df1.add(df2, fill_value=0) # 缺失值按 0 处理

反向算术:radd / rsub 等

反向运算,即参数交换顺序。

方法等价运算
radd(other)other + self
rsub(other)other - self
rmul(other)other * self
rdiv(other)other / self
rtruediv(other)other / self
rfloordiv(other)other // self
rmod(other)other % self
rpow(other)other ** self
s = pd.Series([1, 2, 3])
s.rsub(10)
# 0    9
# 1    8
# 2    7
 
# 等价于
10 - s

10. 比较运算

方法运算符含义
eq()==等于
ne()!=不等于
lt()<小于
le()<=小于等于
gt()>大于
ge()>=大于等于
df = pd.DataFrame({'A': [1, 2, 3]})
 
df.gt(1)
#        A
# 0  False
# 1   True
# 2   True
 
df.eq(2)
df['A'].le(2)
 
# 两个 DataFrame 比较
df1.gt(df2, axis=0)

NaN 与比较

比较结果中的 NaN 通常为 False,因为 NaN 不能确定序关系。

11. combine() / combine_first()

combine()

使用自定义函数将两个对象按元素结合。

df1 = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})
df2 = pd.DataFrame({'A': [5, 6], 'B': [7, 8]})
 
df1.combine(df2, lambda a, b: a if a > b else b)
# 取每个位置的最大值
 
# 自定义填充
df1.combine(df2, np.maximum, fill_value=0)

combine_first()

用另一个对象填补当前对象的缺失值。

df1 = pd.DataFrame({'A': [1, np.nan], 'B': [3, 4]})
df2 = pd.DataFrame({'A': [9, 9]})
 
df1.combine_first(df2)
#      A    B
# 0  1.0  3.0
# 1  9.0  4.0
方法行为
combine(func)用自定义函数逐元素合并
combine_first(other)当前值为 NaN 时用 other 填充

12. update()

用另一个对象的值原地更新当前对象,非 NaN 值覆盖。

df1 = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})
df2 = pd.DataFrame({'A': [10, np.nan]})
 
df1.update(df2)
#       A  B
# 0  10.0  3
# 1   2.0  4

update 是少有的原地修改操作

update() 默认直接修改原对象,使用前建议复制:df1.copy().update(df2)。

13. compare()

逐元素比较两个 DataFrame,显示差异。

df1 = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})
df2 = pd.DataFrame({'A': [1, 9], 'B': [3, 4]})
 
df1.compare(df2)
#      A
#   self other
# 1    2     9
 
# 参数
df1.compare(df2, keep_shape=True)         # 保留原始形状
df1.compare(df2, keep_equal=True)         # 显示相等值
df1.compare(df2, align_axis=0)            # 纵向展示
df1.compare(df2, result_names=('old', 'new'))  # 自定义名称
参数默认值说明
align_axis1差异展示方向(1=左右,0=上下)
keep_shapeFalse是否保留所有位置
keep_equalFalse是否显示相等值
result_names(‘self’, ‘other’)结果列命名

🔗 相关笔记