如何对Dataframe分组后生成元素排列组合?大数据量适配方案咨询
大规模数据集的矢量化处理方案
1. 生成TYPES列
先把SUB、EDGE、PT和0及后续数值列的非空值打包成TYPES列,这里提供两种矢量化方法,适配不同数据规模:
方法一:快速实现(中等规模数据适用)
import pandas as pd # 构造示例DataFrame(替换为你的真实数据) df = pd.DataFrame({ 'PLOT': [117]*5, 'SEED': [1]*5, 'SUB': [1,1,1,1,2], 'EDGE': [1,1,2,2,1], 'PT': [2,3,1,2,1], '0': [8,8,8,6,8], '1': [None, None, None,7,None], '2': [None, None, None,8,None], '3': [None, None, None,None,None] }) # 提取所有数字命名的列 num_cols = [col for col in df.columns if col.isdigit()] # 生成TYPES列:每行打包成字典列表(或元组列表更省内存) df['TYPES'] = df.apply( lambda row: [ {'SUB': row['SUB'], 'EDGE': row['EDGE'], 'PT': row['PT'], 'VAL': val} for val in row[num_cols] if pd.notna(val) ], axis=1 ) # 元组版本(内存更友好): # df['TYPES'] = df.apply( # lambda row: [(row['SUB'], row['EDGE'], row['PT'], val) for val in row[num_cols] if pd.notna(val)], # axis=1 # )
方法二:高矢量化实现(千万级数据适用)
apply在超大规模数据下仍有性能瓶颈,改用melt做完全矢量化处理:
# 展开数值列,过滤空值 melted_df = df.melt( id_vars=['PLOT', 'SEED', 'SUB', 'EDGE', 'PT'], value_vars=num_cols, value_name='VAL' ).dropna(subset=['VAL']) # 按原维度打包成单个TYPES元素 melted_df['TYPES'] = melted_df.apply( lambda row: {'SUB': row['SUB'], 'EDGE': row['EDGE'], 'PT': row['PT'], 'VAL': row['VAL']}, axis=1 ) # 按PLOT/SEED/SUB分组,聚合TYPES列表 df = melted_df.groupby(['PLOT', 'SEED', 'SUB'])['TYPES'].apply(list).reset_index()
2. 按PLOT/SEED分组生成排列组合
同一PLOT和SEED下,基于不同SUB的TYPES生成所有笛卡尔积组合,用itertools.product(C语言实现,效率远高于Python循环):
from itertools import product # 按PLOT/SEED分组,获取每组内各SUB对应的TYPES集合 grouped = df.groupby(['PLOT', 'SEED'])['TYPES'].apply(list).reset_index() # 生成每组的所有排列组合 grouped['PERMUTATIONS'] = grouped['TYPES'].apply(lambda x: list(product(*x))) # 展开结果,保留核心字段 final_result = grouped.explode('PERMUTATIONS').drop(columns=['TYPES'])
存储选择建议
- 元组列表:内存占用比字典低30%-50%,适合千万级数据,后续处理可通过索引对应字段(比如
item[0]对应SUB)。 - 字典列表:可读性强,字段访问更直观,但内存开销大,适合数据规模较小或对可读性要求高的场景。
内容的提问来源于stack exchange,提问作者Lev Zhitnik
相关产品推荐
相关产品推荐

