最佳实践 #

编码规范 #

命名约定 #

python
import pandas as pd
import numpy as np

# DataFrame 命名:使用有意义的名称
df_sales = pd.DataFrame()  # 好
df = pd.DataFrame()        # 不推荐

# Series 命名:使用单数形式
series_price = pd.Series()  # 好
prices = pd.Series()        # 也可以

# 列名:使用小写和下划线
df['unit_price'] = 100  # 好
df['UnitPrice'] = 100   # 不推荐

# 避免使用保留字
# df['class'] = 'A'     # 不推荐
df['category'] = 'A'    # 好

代码组织 #

python
# 导入顺序
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# 常量定义
DATA_PATH = 'data/'
OUTPUT_PATH = 'output/'

# 函数定义
def load_data(filepath):
    return pd.read_csv(filepath)

def process_data(df):
    return df.drop_duplicates()

# 主程序
if __name__ == '__main__':
    df = load_data(DATA_PATH + 'sales.csv')
    df = process_data(df)

常见陷阱 #

链式索引 #

python
import pandas as pd
import numpy as np

df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})

# 陷阱:链式索引
# df[df['A'] > 1]['B'] = 10  # SettingWithCopyWarning

# 解决方案:使用 loc
df.loc[df['A'] > 1, 'B'] = 10

原地修改 #

python
# 陷阱:原地修改可能不按预期工作
# df.drop('A', axis=1, inplace=True)  # 有时会有问题

# 解决方案:重新赋值
df = df.drop('A', axis=1)

索引重置 #

python
# 陷阱:过滤后索引不连续
df_filtered = df[df['A'] > 1]
# print(df_filtered.loc[0])  # 可能报错

# 解决方案:重置索引
df_filtered = df_filtered.reset_index(drop=True)

副本与视图 #

python
# 陷阱:意外修改原数据
subset = df[df['A'] > 1]
subset['B'] = 10  # SettingWithCopyWarning

# 解决方案:显式复制
subset = df[df['A'] > 1].copy()
subset['B'] = 10

类型推断 #

python
# 陷阱:混合类型列
df = pd.DataFrame({'col': [1, 2, 'three']})
# df['col'].sum()  # 可能不是预期结果

# 解决方案:明确类型
df['col'] = pd.to_numeric(df['col'], errors='coerce')

性能技巧 #

向量化操作 #

python
import numpy as np

df = pd.DataFrame({'value': np.random.rand(100000)})

# 慢:循环
def slow_method():
    result = []
    for i in range(len(df)):
        result.append(df.iloc[i]['value'] * 2)
    return result

# 快:向量化
def fast_method():
    return df['value'] * 2

类型优化 #

python
# 优化前
df = pd.DataFrame({
    'small_int': np.random.randint(0, 100, 100000),
    'category': np.random.choice(['A', 'B', 'C'], 100000)
})

print(df.memory_usage(deep=True))

# 优化后
df['small_int'] = df['small_int'].astype('int8')
df['category'] = df['category'].astype('category')

print(df.memory_usage(deep=True))

避免重复计算 #

python
# 不推荐:重复计算
result1 = df[df['category'] == 'A']['value'].mean()
result2 = df[df['category'] == 'A']['value'].sum()
result3 = df[df['category'] == 'A']['value'].std()

# 推荐:一次计算
grouped = df[df['category'] == 'A']['value']
result1 = grouped.mean()
result2 = grouped.sum()
result3 = grouped.std()

# 或使用 agg
results = df[df['category'] == 'A']['value'].agg(['mean', 'sum', 'std'])

数据处理技巧 #

使用 query #

python
# 复杂条件使用 query
result = df.query('category == "A" and value > 100 and region in ["North", "South"]')

# 比
# result = df[(df['category'] == 'A') & (df['value'] > 100) & df['region'].isin(['North', 'South'])]

使用 isin #

python
# 多值匹配使用 isin
result = df[df['category'].isin(['A', 'B', 'C'])]

# 比
# result = df[(df['category'] == 'A') | (df['category'] == 'B') | (df['category'] == 'C')]

使用 np.where #

python
import numpy as np

# 条件赋值
df['level'] = np.where(df['value'] > 100, 'high', 'low')

# 比
# df['level'] = df['value'].apply(lambda x: 'high' if x > 100 else 'low')

使用 np.select #

python
# 多条件赋值
conditions = [
    df['value'] > 100,
    df['value'] > 50,
    df['value'] > 0
]
choices = ['high', 'medium', 'low']
df['level'] = np.select(conditions, choices, default='zero')

调试技巧 #

查看数据 #

python
# 查看基本信息
print(df.info())
print(df.describe())
print(df.head())
print(df.tail())

# 查看缺失值
print(df.isna().sum())

# 查看唯一值
print(df['category'].nunique())
print(df['category'].unique())

检查数据类型 #

python
# 查看数据类型
print(df.dtypes)

# 检查特定列类型
print(df['value'].dtype)

# 类型推断
print(df.infer_objects().dtypes)

逐步调试 #

python
def process_data(df):
    print(f"Step 1 - Input shape: {df.shape}")
    
    df = df.drop_duplicates()
    print(f"Step 2 - After drop_duplicates: {df.shape}")
    
    df = df.dropna()
    print(f"Step 3 - After dropna: {df.shape}")
    
    df['total'] = df['quantity'] * df['price']
    print(f"Step 4 - After adding column: {df.shape}")
    
    return df

代码质量 #

函数文档 #

python
def calculate_metrics(df, group_column, value_column):
    """
    计算分组指标
    
    Parameters
    ----------
    df : pd.DataFrame
        输入数据
    group_column : str
        分组列名
    value_column : str
        数值列名
    
    Returns
    -------
    pd.DataFrame
        分组统计结果
    """
    return df.groupby(group_column)[value_column].agg(['mean', 'std', 'count'])

类型提示 #

python
from typing import Union, List

def filter_data(
    df: pd.DataFrame,
    column: str,
    values: Union[List, str]
) -> pd.DataFrame:
    return df[df[column].isin(values)]

单元测试 #

python
import unittest

class TestDataProcessing(unittest.TestCase):
    def setUp(self):
        self.df = pd.DataFrame({
            'A': [1, 2, 3],
            'B': [4, 5, 6]
        })
    
    def test_add_column(self):
        result = self.df.assign(C=self.df['A'] + self.df['B'])
        self.assertIn('C', result.columns)
        self.assertEqual(result['C'].iloc[0], 5)

if __name__ == '__main__':
    unittest.main()

最佳实践清单 #

text
┌─────────────────────────────────────────────────────────────┐
│                    最佳实践清单                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  编码规范                                                   │
│  □ 使用有意义的变量名                                       │
│  □ 遵循 PEP 8 风格                                          │
│  □ 添加必要的注释和文档                                     │
│                                                             │
│  数据处理                                                   │
│  □ 使用 loc 替代链式索引                                    │
│  □ 使用 copy() 避免意外修改                                 │
│  □ 处理后重置索引                                           │
│                                                             │
│  性能优化                                                   │
│  □ 使用向量化操作                                           │
│  □ 选择合适的数据类型                                       │
│  □ 避免重复计算                                             │
│                                                             │
│  错误处理                                                   │
│  □ 验证输入数据                                             │
│  □ 处理缺失值和异常值                                       │
│  □ 添加适当的错误处理                                       │
│                                                             │
│  代码质量                                                   │
│  □ 编写可复用的函数                                         │
│  □ 添加单元测试                                             │
│  □ 进行代码审查                                             │
│                                                             │
└─────────────────────────────────────────────────────────────┘

总结 #

恭喜你完成了 Pandas 完全指南的学习!你已经掌握了:

  1. 基础入门:Pandas 简介、安装配置
  2. 核心数据结构:Series、DataFrame、数据类型、索引
  3. 数据处理:数据读写、选择、过滤、清洗
  4. 数据分析:统计分析、分组聚合、合并连接、数据重塑
  5. 高级主题:时间序列、可视化、性能优化、高级操作
  6. 实战应用:数据分析实战、数据管道、最佳实践

继续练习和实践,你将成为 Pandas 专家!

最后更新:2026-04-04