mean(axis=1)能算行均值,但默认跳过NaN、要求纯数值类型、结果按原索引对齐;需注意skipna=False、select_dtypes、values转np.array及assign对齐等细节。

mean(axis=1) 真的能直接算行均值?先看它到底认不认 NaN
不能默认就用 mean(axis=1),它默认会跳过 NaN —— 这是多数人没意识到的“温柔陷阱”。如果你的数据里混着缺失值,结果看似合理,实则悄悄丢掉了整行参与计算的权重。
- 想保留
NaN传播(即某行有NaN就让结果也是NaN):加参数skipna=False - 想强制把
NaN当 0 算:得先用fillna(0),再调mean(axis=1) - 如果列里混着字符串或对象类型,
mean()会直接报错TypeError: Could not convert ... to numeric,必须提前用select_dtypes(include='number')过滤
axis=1 和 axis=0 到底谁横谁竖?别靠“行列”字面猜
axis 是“塌缩掉的轴”,不是“要操作的轴”。axis=1 意味着“把列这个维度压平”,结果是一列(每个元素对应原 DataFrame 的一行),所以才是行均值。很多人写成 axis=0 还纳闷为什么出来的是列均值。
-
df.mean(axis=0)→ 返回Series,索引是列名,值是每列的均值 -
df.mean(axis=1)→ 返回Series,索引是原index,值是每行的均值 - 在
apply()里写lambda x: x.mean()默认也是按行(因为apply默认axis=0,但传给函数的是列;若想按行apply,得显式写axis=1)
性能差别大不大?小数据无所谓,大数据得绕开 mean(axis=1)
对上万行、上百列的 DataFrame,mean(axis=1) 内部走的是通用路径,比纯数值数组慢不少。真要压榨性能,得切到 NumPy 底层。
- 确认全是数值:用
df.values转ndarray,再调np.mean(df.values, axis=1) - 含缺失值且需跳过:
np.nanmean(df.values, axis=1)更快,且行为和df.mean(axis=1)一致 - 注意:
df.values会丢失 dtype 信息,如果原 DataFrame 有混合类型(比如 int + float),values可能全转成object,这时np.mean会失败 —— 必须先astype(float)
结果怎么塞回去?别直接赋值 df['row_mean'] = ... 后发现对不上
如果原 DataFrame 有重复索引或非连续索引,df.mean(axis=1) 返回的 Series 会按原索引对齐,但你手动赋值时容易忽略这点,导致新列顺序错乱或填充进错误行。
- 安全做法:用
df.assign(row_mean=df.mean(axis=1)),自动对齐索引 - 或者明确重置:先
row_means = df.mean(axis=1).rename('row_mean'),再pd.concat([df, row_means], axis=1) - 如果原
df.index是RangeIndex且未改动,直接df['row_mean'] = df.mean(axis=1)没问题;但只要 index 曾被reindex、loc过滤或合并过,就得查对齐










