无需手动编写循环,实现基于指定列的DataFrame动态过滤
通用化实现多维度分组含总计的求和统计
你可以通过生成所有列的分组组合(包含"total"),结合动态筛选的方式实现通用化,无需手动编写嵌套循环。以下是两种可行的实现方案:
方案一:直观的笛卡尔积组合筛选
这种方法直接生成所有可能的列值组合(包含各列的"total"),然后对每个组合动态筛选数据并计算总和,不管col_list有多少列都能自动适配:
import pandas as pd df = pd.DataFrame({ 'Col1':['A','A','A','B','B','B'], 'Col2':['AA','AB','AC','BA','BB','BC'], 'Val':[1,2,3,1,2,3] }) def get_data(df, col_list): # 为每个列生成包含"total"的唯一值列表 level_values = [['total'] + df[col].unique().tolist() for col in col_list] # 生成所有列值的笛卡尔积组合 all_combinations = pd.MultiIndex.from_product(level_values, names=col_list) for combo in all_combinations: # 构建筛选条件:非"total"的列对应过滤,"total"列保留全部数据 mask = pd.Series([True] * len(df)) for col, val in zip(col_list, combo): if val != 'total': mask &= (df[col] == val) # 计算当前组合的Val总和并格式化输出 total_val = df.loc[mask, 'Val'].sum() print(' | '.join(map(str, combo)) + f' | {total_val}') # 调用函数 col_list = ['Col1','Col2'] get_data(df, col_list)
方案二:基于分组汇总的高效实现
如果数据量较大,推荐使用pandas的分组功能先计算各类统计值,再补充总计行,效率更高:
import pandas as pd df = pd.DataFrame({ 'Col1':['A','A','A','B','B','B'], 'Col2':['AA','AB','AC','BA','BB','BC'], 'Val':[1,2,3,1,2,3] }) def get_data(df, col_list): # 先计算所有非总计的分组求和结果 grouped = df.groupby(col_list)['Val'].sum().reset_index() # 生成各层级的总计数据 totals = [] # 生成从全总计到各列单独分组的总计 for i in range(len(col_list) + 1): if i == 0: # 全量总计 total_row = {col: 'total' for col in col_list} total_row['Val'] = df['Val'].sum() totals.append(pd.DataFrame([total_row])) else: # 前i列分组,剩余列设为total的总计 partial_total = df.groupby(col_list[:i])['Val'].sum().reset_index() for col in col_list[i:]: partial_total[col] = 'total' totals.append(partial_total) # 合并所有结果并按要求排序 all_results = pd.concat(totals + [grouped], ignore_index=True) # 构建排序键,让total排在每个列的最前面 sort_cols = [] for col in col_list: all_results[f'{col}_sort'] = all_results[col].apply(lambda x: 0 if x == 'total' else 1) sort_cols.extend([f'{col}_sort', col]) all_results = all_results.sort_values(sort_cols).drop([f'{col}_sort' for col in col_list], axis=1) # 格式化输出 for _, row in all_results.iterrows(): print(' | '.join([str(row[col]) for col in col_list]) + f' | {row["Val"]}') return all_results # 调用函数 col_list = ['Col1','Col2'] get_data(df, col_list)
两种方案的输出都和你提供的示例完全一致,且col_list可以扩展到任意数量的列,无需修改函数内部逻辑。
内容的提问来源于stack exchange,提问作者user22681865
相关产品推荐
相关产品推荐

