如何基于条件在主DataFrame中新增标记列?解决合并超限问题
高效实现主DataFrame的条件标记(避免合并行数爆炸)
直接合并DataFrame会产生大量笛卡尔积行,导致内存溢出,我们可以通过预处理小型DataFrame+逐行映射判断的方式解决这个问题,具体步骤如下:
1. 合并并预处理所有小型DataFrame
先把所有小型DataFrame合并到一起,然后按BB列分组,收集每个BB对应的所有AA值,生成一个映射字典,这样能快速查找主DataFrame中A列对应的候选AA值。
import pandas as pd # 示例主DataFrame data = [['Tom', 10], ['Nick', 15], ['Juli', 14], ['Tom', 7], ['Juli', 9]] main_df = pd.DataFrame(data, columns=['A', 'B']) # 示例小型DataFrame(模拟三个小型DataFrame) data1 = [[5, 'Juli'], [17, 'Tom'], [6, 'Juli'], [8,'Tom']] df1 = pd.DataFrame(data1, columns=['AA', 'BB']) data2 = [[12, 'Tom'], [8, 'Juli']] df2 = pd.DataFrame(data2, columns=['AA', 'BB']) data3 = [[10, 'Nick'], [14, 'Juli']] df3 = pd.DataFrame(data3, columns=['AA', 'BB']) # 合并所有小型DataFrame all_small_dfs = pd.concat([df1, df2, df3]) # 生成BB到对应AA列表的映射字典 bb_to_aas = all_small_dfs.groupby('BB')['AA'].apply(list).to_dict()
2. 定义条件判断函数
对主DataFrame的每一行,执行两个判断:
- 当前行的
A是否存在于映射字典的键中(即存在于任意小型DataFrame的BB列) - 是否存在对应的
AA值,使得|B - AA| < 5
def mark_condition(row): # 获取当前A对应的所有AA值 aa_candidates = bb_to_aas.get(row['A'], []) if not aa_candidates: return '' # 检查是否有满足差值条件的AA return 'X' if any(abs(row['B'] - aa) < 5 for aa in aa_candidates) else ''
3. 生成标记列C
用apply逐行应用判断函数,生成结果列:
main_df['C'] = main_df.apply(mark_condition, axis=1)
运行后得到的结果:
A B C 0 Tom 10 X 1 Nick 15 2 Juli 14 X 3 Tom 7 X 4 Juli 9 X
为什么这个方法更高效?
- 避免了全量合并产生的笛卡尔积,不会出现行数爆炸的问题
- 映射字典的查找是O(1)时间复杂度,逐行判断的计算量远小于合并后的大规模数据处理
- 即使小型DataFrame数量增加,预处理步骤的开销也很低
内容的提问来源于stack exchange,提问作者be84
相关产品推荐
相关产品推荐

