性能优化
处理 pandas DataFrame 数据清洗、聚合…
当需要用 pandas 对 DataFrame 做数据检查、清洗、转换、分组聚合、合并连接、透视或时间序列重采样时,按此经验高效且安全地编写代码。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 49/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
处理 pandas DataFrame 通用
解决思路
- 先评估数据结构:执行 print(df.dtypes)、print(df.memory_usage(deep=True).sum() / 1e6, "MB")、print(df.isna().sum())、print(df.describe(include="all")) 检查类型、内存、缺失值、数据质量。
- 设计转换方案:规划向量化操作,避免 Python 循环,确定索引策略。
- 高效实现:使用向量化方法、方法链、正确的索引方式。
- 验证结果:用 assert result.shape[0] == expected_rows, f"Row count mismatch: {result.shape[0]}"、assert result.isna().sum().sum() == 0, "Unexpected nulls after transform"、assert set(result.columns) == expected_cols 检查 dtype、形状、空值数和行数。
- 优化:分析内存,应用 category 类型,必要时分块处理。
- 按上下文加载参考文档:DataFrame 操作加载 references/dataframe-operations.md,用于索引、选择、过滤、排序。
- 按上下文加载参考文档:数据清洗加载 references/data-cleaning.md,用于缺失值、重复值、类型转换。
- 按上下文加载参考文档:聚合与 GroupBy 加载 references/aggregation-groupby.md,用于 GroupBy、pivot、crosstab、聚合。
- 按上下文加载参考文档:合并与连接加载 references/merging-joining.md,用于 merge、join、concat、combine 策略。
- 按上下文加载参考文档:性能优化加载 references/performance-optimization.md,用于内存使用、向量化、分块。
- 向量化操作:不要逐行迭代,例如避免 for i, row in df.iterrows(): df.at[i, 'tax'] = row['price'] * 0.2;改用 df['tax'] = df['price'] * 0.2。
- 安全子集赋值:避免链式索引 df['A']['B'] = 1;在修改子集时使用 subset = df.loc[df['status'] == 'active', :].copy(),再执行 subset['score'] = subset['score'].fillna(0)。
- GroupBy 聚合:使用 summary = (df.groupby(['region', 'category'], observed=True).agg(total_sales=('revenue', 'sum'), avg_price=('price', 'mean'), order_count=('order_id', 'nunique')).reset_index())。
- 带验证的合并:使用 pd.merge(left_df, right_df, on=['customer_id', 'date'], how='left', validate='m:1', indicator=True);检查 unmatched = merged[merged['_merge'] != 'both'],打印未匹配行数,再 merged.drop(columns=['_merge'], inplace=True)。
- 缺失值处理:对数值缺口使用 df['price'] = df['price'].ffill().interpolate(method='linear');分类列用众数填充,数值列用中位数填充。
- 时间序列重采样:使用 daily = (df.set_index('timestamp').resample('D').agg({'revenue': 'sum', 'sessions': 'count'}).fillna(0))。
- 透视表:使用 pivot = df.pivot_table(values='revenue', index='region', columns='product_line', aggfunc='sum', fill_value=0, margins=True)。
- 内存优化:将低基数分类列转为 category:df['category'] = df['category'].astype('category');将计数降为整数:df['count'] = pd.to_numeric(df['count'], downcast='integer');将分数降为浮点:df['score'] = pd.to_numeric(df['score'], downcast='float');并打印优化后内存 print(df.memory_usage(deep=True).sum() / 1e6, "MB after optimization")。
- 必须使用向量化操作代替循环。
- 必须设置合适 dtype,低基数字符串使用 categorical。
- 必须用 .memory_usage(deep=True) 检查内存使用。
- 必须显式处理缺失值,不要静默丢弃。
- 必须使用方法链提高可读性。
- 必须在操作过程中保持索引完整性。
- 必须在转换前后验证数据质量。
- 修改子集时必须使用 .copy() 以避免 SettingWithCopyWarning。
- 不得使用 .iterrows() 逐行遍历 DataFrame,除非绝对必要。
- 不得使用链式索引 df['A']['B'],应使用 .loc[] 或 .iloc[]。
- 不得忽略 SettingWithCopyWarning。
- 不得在不分块的情况下加载整个大型数据集。
- 不得使用已弃用方法 .ix、.append(),应使用 pd.concat()。
- 不得为 pandas 可完成的操作转换为 Python list。
- 不得未经校验就假设数据是干净的。
- 输出时提供使用向量化操作和正确索引的代码。
- 输出时添加注释解释复杂转换。
- 如果数据集较大,输出内存/性能考量。
- 输出数据校验检查(dtype、空值、形状)。
适用边界 · 注意事项
- 不适用于无法放入单机内存且不能分块处理的大数据集;这类场景应考虑 Dask、Spark 或 Polars 等方案。
- 不适用于需要流式实时处理、复杂图计算或深度学习等 pandas 非优势场景。
- 不适用于非 Python/pandas 技术栈的数据处理任务。