大数据集下基于Pandas的新列最优创建方案咨询
用Pandas实现需求的解决方案
核心思路
先建立Column B值与对应Column C值的映射关系,再针对每个ID计算其Column B的前序值(B-1、B-2、B-3)对应的历史C值,最后用当前C值除以历史C值生成新列,无对应历史值则填充NaN。
情况1:Column B值唯一(无重复)
如果数据中Column B的值是唯一的,可按以下步骤快速实现:
步骤1:构造示例数据
import pandas as pd import numpy as np # 模拟原始数据 data = { 'ID': [1, 2, 3, 4, 5], 'Column B': [5, 7, 8, 6, 9], 'Column C': [10, 4, 36, 20, 18] } df = pd.DataFrame(data)
步骤2:创建B到C的映射字典
b_to_c = df.set_index('Column B')['Column C'].to_dict()
步骤3:计算新列col1、col2、col3
通过map快速获取前序B值对应的C,再做除法运算:
# col1: 当前C / (B-1对应的C) df['col1'] = df.apply(lambda row: row['Column C'] / b_to_c.get(row['Column B'] - 1, np.nan), axis=1) # col2: 当前C / (B-2对应的C) df['col2'] = df.apply(lambda row: row['Column C'] / b_to_c.get(row['Column B'] - 2, np.nan), axis=1) # col3: 当前C / (B-3对应的C) df['col3'] = df.apply(lambda row: row['Column C'] / b_to_c.get(row['Column B'] - 3, np.nan), axis=1)
结果示例
| ID | Column B | Column C | col1 | col2 | col3 |
|---|---|---|---|---|---|
| 1 | 5 | 10 | NaN | NaN | NaN |
| 2 | 7 | 4 | NaN | 0.4 | NaN |
| 3 | 8 | 36 | 9.0 | 1.8 | NaN |
| 4 | 6 | 20 | 2.0 | NaN | 20.0 |
| 5 | 9 | 18 | 0.45 | 4.5 | 1.8 |
情况2:Column B值存在重复(取历史最近值)
如果数据中有重复的Column B值,且需要取当前ID之前最近的对应前序B值的C,推荐用向量化操作优化效率:
步骤1:确保数据按ID排序
先保证数据按ID递增排序,确保历史顺序正确:
df = df.sort_values('ID').reset_index(drop=True)
步骤2:用merge实现向量化计算
# 循环处理col1到col3的offset(1、2、3) for offset in [1,2,3]: # 创建临时表:将B值+offset作为匹配键,关联历史C值 temp = df[['Column B', 'Column C']].copy() temp['Column B'] = temp['Column B'] + offset temp.rename(columns={'Column C': f'hist_c{offset}'}, inplace=True) # 左连接原表,无匹配则填充NaN df = df.merge(temp, on='Column B', how='left') # 计算比值生成新列 df[f'col{offset}'] = df['Column C'] / df[f'hist_c{offset}'] # 删除临时辅助列 df.drop(f'hist_c{offset}', axis=1, inplace=True)
这种方法避免了逐行循环,适合百万级以上的大数据集,运行效率远高于iterrows。
注意事项
- 如果你的“前序值”指的是行的前n行而非B数值减n,可直接用
df['Column C'].shift(n)获取历史值后计算比值。 - 处理超大数据集时,建议先对Column B建立索引,进一步提升
merge或map的查询效率。
内容的提问来源于stack exchange,提问作者alex4994
相关产品推荐
相关产品推荐

