如何在Pandas中合并多个DataFrame的describe()统计结果?
嘿,这个问题问到点子上了!把所有CSV拼接成一个大DataFrame再调用describe()确实是最直接的办法,但绝对不是最优解——尤其是当你处理的文件数量多、单个文件体积大的时候,这种做法会吃掉大量内存,甚至可能直接导致程序崩溃。
我给你推荐一套更高效的方案,分两步走:先搞定每个文件的单独统计,再高效计算全局的合并统计,全程不用加载所有数据到内存。
第一步:计算单个文件的统计量
我们可以遍历目录里的每个CSV,加载后只提取你需要的count、mean、min、max这几个统计量,不用跑完整的describe()(毕竟它还会计算你不需要的分位数、标准差这些)。代码大概是这样的:
import pandas as pd import os # 定义我们需要的统计量,避免计算多余内容 target_stats = ['count', 'mean', 'min', 'max'] csv_dir = "/path/to/your/csv/folder" # 替换成你的目录路径 file_stat_list = [] for filename in os.listdir(csv_dir): if not filename.endswith(".csv"): continue file_path = os.path.join(csv_dir, filename) # 读取当前CSV文件 df = pd.read_csv(file_path) # 提取目标统计量,转置后方便后续合并 file_stats = df.describe().loc[target_stats].T # 给每条统计结果加上文件名标识,方便区分 file_stats['filename'] = filename file_stat_list.append(file_stats) # 把所有单个文件的统计结果合并成一个DataFrame all_single_file_stats = pd.concat(file_stat_list) print("每个文件的统计结果:") print(all_single_file_stats)
第二步:高效计算全局合并统计
如果直接拼接所有文件再计算,内存压力太大。我们可以在遍历文件的过程中,累加计算全局统计需要的核心中间值:
count:直接累加每个列的非空行数sum:用每个列的count * mean得到该列的总和,然后累加(这样后续可以算出全局均值)min:全程记录每个列的最小值max:全程记录每个列的最大值
具体代码实现如下:
# 初始化全局统计的中间变量,第一次遍历文件时会被赋值 global_col_counts = None global_col_sums = None global_col_mins = None global_col_maxs = None for filename in os.listdir(csv_dir): if not filename.endswith(".csv"): continue file_path = os.path.join(csv_dir, filename) df = pd.read_csv(file_path) # 计算当前文件各列的关键统计值 curr_counts = df.count() curr_means = df.mean(numeric_only=True) curr_sums = curr_counts * curr_means curr_mins = df.min(numeric_only=True) curr_maxs = df.max(numeric_only=True) # 第一次循环时初始化全局变量 if global_col_counts is None: global_col_counts = curr_counts global_col_sums = curr_sums global_col_mins = curr_mins global_col_maxs = curr_maxs else: # 累加更新全局变量 global_col_counts += curr_counts global_col_sums += curr_sums # 取两个结果中的最小值/最大值 global_col_mins = pd.concat([global_col_mins, curr_mins], axis=1).min(axis=1) global_col_maxs = pd.concat([global_col_maxs, curr_maxs], axis=1).max(axis=1) # 计算全局均值 global_col_means = global_col_sums / global_col_counts # 整理成最终的全局统计DataFrame global_stats = pd.DataFrame({ "count": global_col_counts, "mean": global_col_means, "min": global_col_mins, "max": global_col_maxs }) print("\n全局合并统计结果:") print(global_stats)
额外优化:处理超大单个CSV
如果你的单个CSV文件大到连一次性加载都困难,可以用pandas.read_csv的chunksize参数分块读取,然后对每个块计算统计量再累加,比如写个辅助函数:
def calculate_large_file_stats(file_path, chunksize=10000): """分块读取超大CSV,计算其统计量""" chunk_counts = None chunk_sums = None chunk_mins = None chunk_maxs = None for chunk in pd.read_csv(file_path, chunksize=chunksize): curr_counts = chunk.count() curr_sums = chunk.sum(numeric_only=True) curr_mins = chunk.min(numeric_only=True) curr_maxs = chunk.max(numeric_only=True) if chunk_counts is None: chunk_counts = curr_counts chunk_sums = curr_sums chunk_mins = curr_mins chunk_maxs = curr_maxs else: chunk_counts += curr_counts chunk_sums += curr_sums chunk_mins = pd.concat([chunk_mins, curr_mins], axis=1).min(axis=1) chunk_maxs = pd.concat([chunk_maxs, curr_maxs], axis=1).max(axis=1) chunk_means = chunk_sums / chunk_counts return pd.Series({ "count": chunk_counts, "mean": chunk_means, "min": chunk_mins, "max": chunk_maxs })
之后在遍历文件的时候,调用这个函数代替直接pd.read_csv就行,完美适配超大文件场景。
内容的提问来源于stack exchange,提问作者xjcl
相关产品推荐
相关产品推荐

