Pandas高效替换DataFrame单元格值:按Signal列及客户分组条件
高性能处理大型DataFrame的Signal值替换需求
问题场景
给定如下DataFrame:
import pandas as pd df = pd.DataFrame({'cust': {0: 'A', 1: 'A', 2: 'A', 3: 'A', 4: 'B', 5: 'B', 6: 'B', 7: 'B', 8: 'B'}, 'value': {0: 6, 1: 10, 2: 11, 3: 15, 4: 6, 5: 12, 6: 21, 7: 29, 8: 33}, 'signal': {0: 0, 1: 1, 2: 1, 3: 0, 4: 1, 5: 0, 6: 0, 7: 0, 8: 0}})需求:当
signal != 0时,将对应行的value替换为该客户的上一行value值;若该客户无历史行(如索引4的B客户),则替换为0。需要适配5000万行的大型DataFrame,保证高性能。
高性能解决方案
针对大数据量场景,必须避免循环操作,采用pandas的矢量化分组操作来实现,代码如下:
import pandas as pd # 构造示例数据(实际场景可直接使用你的大型DataFrame) df = pd.DataFrame({'cust': {0: 'A', 1: 'A', 2: 'A', 3: 'A', 4: 'B', 5: 'B', 6: 'B', 7: 'B', 8: 'B'}, 'value': {0: 6, 1: 10, 2: 11, 3: 15, 4: 6, 5: 12, 6: 21, 7: 29, 8: 33}, 'signal': {0: 0, 1: 1, 2: 1, 3: 0, 4: 1, 5: 0, 6: 0, 7: 0, 8: 0}}) # 核心处理逻辑 df['value'] = df['value'].mask( df['signal'] != 0, # 触发替换的条件:signal不为0 df.groupby('cust')['value'].shift(1).fillna(0) # 替换值:客户上一行value,无则为0 ) # 输出处理后的结果 print(df)
代码解释
groupby('cust')['value'].shift(1):按客户分组后,对每组的value执行向下偏移一行操作,这样就能获取当前行对应的客户上一行value;每组的第一行会得到NaN(因为没有上一行数据)。.fillna(0):将分组偏移后产生的NaN替换为0,满足“无历史行则替换为0”的需求。df['value'].mask(condition, replacement):这是pandas的矢量化方法,当condition为True时,用replacement的值替换原value,否则保留原值。矢量化操作是pandas处理大数据的核心,比循环快几个数量级,完全能支撑5000万行的数据规模。
处理后结果
cust value signal 0 A 6.0 0 1 A 6.0 1 2 A 10.0 1 3 A 15.0 0 4 B 0.0 1 5 B 12.0 0 6 B 21.0 0 7 B 29.0 0 8 B 33.0 0
内容的提问来源于stack exchange,提问作者user3225309
相关产品推荐
相关产品推荐

