You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Pandas DataFrame中对列的子集执行计算并修改原数据

问题场景

现有如下数据集(通过pd.wide_to_long生成):

famid  birth  age   ht
0       1      1  one  2.8
1       1      1  two  3.4
2       1      2  one  2.9
3       1      2  two  3.8
4       1      3  one  2.2
5       1      3  two  2.9

需要仅修改df['ht']中满足df['age'] == 'one'的子集数据,且不新建列。尝试以下代码后数据未变化,还触发**"A value is trying to be set on a copy of a slice from a DataFrame"**警告:

df[df['age']=='one']['ht'] = df[df['age']=='one']['ht']*10**6

尝试过df.mask()和df.where()方法也未生效,求正确实现方式。

可复现数据集代码:

import pandas as pd

df = pd.DataFrame({
    'famid': [1, 1, 1, 2, 2, 2, 3, 3, 3],
    'birth': [1, 2, 3, 1, 2, 3, 1, 2, 3],
    'ht_one': [2.8, 2.9, 2.2, 2, 1.8, 1.9, 2.2, 2.3, 2.1],
    'ht_two': [3.4, 3.8, 2.9, 3.2, 2.8, 2.4, 3.3, 3.4, 2.9]
})
df = pd.wide_to_long(df, stubnames='ht', i=['famid', 'birth'], j='age',
                    sep='_', suffix=r'\w+')
df.reset_index(inplace = True)

问题根源

原代码用了链式索引df[df['age']=='one']['ht'],这种写法会返回原DataFrame的副本而非视图,对副本赋值不会影响原DataFrame,这就是数据没变化且触发警告的原因。

正确实现方法

方法1:使用.loc定位赋值(推荐)

通过.loc直接定位到目标行和列,直接修改原DataFrame:

df.loc[df['age'] == 'one', 'ht'] *= 10**6

也可以写成展开形式:

df.loc[df['age'] == 'one', 'ht'] = df.loc[df['age'] == 'one', 'ht'] * 10**6

.loc是Pandas官方推荐的修改数据方式,能确保操作的是原DataFrame的视图,避免副本问题。

方法2:使用np.where替换

借助numpy.where根据条件生成新值,直接替换原列:

import numpy as np
df['ht'] = np.where(df['age'] == 'one', df['ht']*10**6, df['ht'])

方法3:正确使用mask/where

之前用这两个方法没生效是因为未正确赋值,正确写法如下:

  • mask:当条件为True时替换对应值
df['ht'] = df['ht'].mask(df['age'] == 'one', df['ht']*10**6)
  • where:当条件为False时替换对应值,因此需要取反判断条件
df['ht'] = df['ht'].where(df['age'] != 'one', df['ht']*10**6)

内容的提问来源于stack exchange,提问作者vestland

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 18:10:49