第一次接触Pandas时,我被它简洁的API设计震撼到了——用几行代码就能完成Excel中需要复杂公式才能实现的操作。在电商公司做了三年数据分析后,我整理了一份高频使用的Pandas功能清单,这些功能覆盖了我日常80%的工作场景。不同于官方文档的全面介绍,这里只聚焦真正实用的核心功能,每个技巧都经过真实业务场景验证。
Pandas特别适合处理表格型数据,比如销售记录、用户行为日志、库存清单等结构化数据。它的DataFrame结构让数据操作变得直观,而背后基于NumPy的实现又保证了处理效率。我见过不少同事一开始用Excel处理数据,当数据量超过10万行就开始卡顿,转而学习Pandas后效率提升明显。
实际工作中数据来源五花八门,Pandas的read_*系列函数是处理多源数据的统一入口。最常用的是读取CSV:
python复制df = pd.read_csv('sales.csv', encoding='gbk', parse_dates=['order_date'])
这里有两个实用参数:
encoding指定中文编码(国内企业数据常用gbk)parse_dates自动将指定列转为datetime类型对于Excel文件,我习惯先查看所有sheet名:
python复制xl = pd.ExcelFile('report.xlsx')
print(xl.sheet_names) # 查看所有工作表
df = pd.read_excel(xl, 'Sheet1')
踩坑提醒:读取大型CSV时,使用
chunksize参数分块加载避免内存溢出,比如chunksize=10000表示每次读取1万行
拿到新数据集后,我会用这套组合拳快速掌握数据情况:
python复制df.head(3) # 查看前3行样本
df.info() # 查看列数据类型和缺失情况
df.describe() # 数值型列统计摘要
df['category'].value_counts() # 查看分类分布
特别说明info()的输出含义:
RangeIndex:行数范围Non-Null Count:非空值数量Dtype:列数据类型memory usage:内存占用(大数据集需关注)缺失值处理是清洗工作的重头戏。我常用的处理策略:
python复制df.dropna(subset=['price'], inplace=True) # 删除price列缺失的行
python复制df['age'].fillna(df['age'].median(), inplace=True) # 中位数填充
df['department'].fillna('未知部门', inplace=True) # 固定值填充
python复制df['is_income_missing'] = df['income'].isna() # 新增标记列
经验之谈:电商数据中,用户性别为空的往往购买转化率更低,这种缺失值得单独分析
数据类型错误会导致各种诡异问题。这是我的类型转换checklist:
python复制df['price'] = pd.to_numeric(df['price'], errors='coerce') # 无效值转NaN
python复制df['order_time'] = pd.to_datetime(df['order_time'], format='%Y/%m/%d %H:%M')
python复制df['city'] = df['city'].astype('category') # 内存占用减少80%
常见踩坑场景:
筛选数据最常用的方法是布尔索引。几个实用技巧:
python复制mask = (df['age'] > 30) & (df['city'] == '北京')
df[mask]
python复制df.query('30 < age < 50 and gender == "F"')
python复制df[df['product_name'].str.contains('手机', na=False)]
性能提示:大数据集避免对字符串列使用
str.contains,考虑先用df['col'].unique()获取唯一值再匹配
排序不只是sort_values那么简单:
python复制df.sort_values(['department', 'salary'], ascending=[True, False])
python复制cat_order = ['初级', '中级', '高级']
df['level'] = pd.Categorical(df['level'], categories=cat_order, ordered=True)
df.sort_values('level')
python复制df.sample(n=1000, random_state=42) # 固定随机种子可复现
groupby是数据分析的核心操作,但很多人只用到皮毛:
python复制agg_df = df.groupby(['year', 'department']).agg({
'sales': ['sum', 'mean'],
'profit': lambda x: x[x>0].mean() # 自定义聚合
})
python复制# 筛选销售额超过组内平均值50%的记录
df.groupby('category').filter(lambda g: g['sales'].mean() * 1.5 < g['sales'])
python复制def top_n(df, n=3, column='sales'):
return df.sort_values(column, ascending=False).head(n)
df.groupby('category').apply(top_n)
pivot_table是快速分析交叉表的利器:
python复制pd.pivot_table(df,
index='department',
columns='year',
values='salary',
aggfunc=['mean', 'count'],
margins=True, # 添加总计
fill_value=0)
高级技巧:
pd.Grouper实现时间维度分组:python复制df.pivot_table(index=pd.Grouper(key='date', freq='M'),
columns='product',
values='sales')
实际业务中经常需要合并多个数据源:
python复制pd.concat([df1, df2], ignore_index=True)
python复制pd.merge(orders, users,
left_on='user_id',
right_on='id',
how='left')
python复制products.join(prices, how='inner')
性能提示:大数据集合并时,先对连接键
on列排序可提升速度
python复制pd.melt(df,
id_vars=['date', 'product'],
value_vars=['q1', 'q2', 'q3', 'q4'],
var_name='quarter',
value_name='sales')
python复制df.pivot(index='date',
columns='product',
values='sales')
时间序列分析必备技能:
python复制df['year'] = df['order_time'].dt.year
df['day_of_week'] = df['order_time'].dt.day_name()
python复制df['time_utc'] = df['time_local'].dt.tz_localize('Asia/Shanghai').dt.tz_convert('UTC')
python复制df.set_index('time').resample('D')['sales'].sum()
移动平均只是开始,更多窗口函数:
python复制df['7d_avg'] = df['sales'].rolling(7).mean()
python复制df['30d_min'] = df['price'].rolling(30, min_periods=10).min()
python复制df['cum_max'] = df['users'].expanding().max()
当数据超过百万行时,内存优化很关键:
python复制dtypes = {
'id': 'int32',
'price': 'float32',
'category': 'category'
}
df = pd.read_csv('large.csv', dtype=dtypes)
python复制chunk_iter = pd.read_csv('huge.csv', chunksize=100000)
results = []
for chunk in chunk_iter:
results.append(chunk.groupby('dept')['sales'].sum())
final = pd.concat(results).groupby(level=0).sum()
python复制df.eval('profit = revenue - cost', inplace=True)
python复制# 错误方式(会报SettingWithCopyWarning)
df[df['age']>30]['salary'] = 0
# 正确方式
df.loc[df['age']>30, 'salary'] = 0
python复制from numba import jit
@jit
def complex_calc(ser):
# 复杂计算逻辑
return result
df['new_col'] = complex_calc(df['values'])
python复制with pd.ExcelWriter('report.xlsx') as writer:
df.to_excel(writer, sheet_name='Summary')
# 添加Excel格式
workbook = writer.book
worksheet = writer.sheets['Summary']
format1 = workbook.add_format({'num_format': '#,##0'})
worksheet.set_column('B:B', None, format1)
python复制print(df.head().to_markdown(tablefmt="github"))
Pandas内置的plot方法能快速可视化:
python复制df.groupby('month')['sales'].sum().plot(
kind='bar',
title='Monthly Sales',
figsize=(10, 6),
color='skyblue'
)
高级用法:
python复制ax = df.plot.scatter(x='age', y='income', alpha=0.3)
df.groupby('age')['income'].median().plot(ax=ax, color='red')
结合一个真实案例展示Pandas的综合应用:
python复制user_cycle = df.groupby('user_id')['order_date'].agg(['min', 'max'])
user_cycle['cycle_days'] = (user_cycle['max'] - user_cycle['min']).dt.days
python复制rfm = df.groupby('user_id').agg({
'order_date': lambda x: (pd.to_datetime('today') - x.max()).days,
'order_id': 'count',
'amount': 'sum'
})
rfm.columns = ['recency', 'frequency', 'monetary']
python复制rfm['r_score'] = pd.qcut(rfm['recency'], q=5, labels=False)
rfm['f_score'] = pd.qcut(rfm['frequency'], q=5, labels=False)
rfm['m_score'] = pd.qcut(rfm['monetary'], q=5, labels=False)
rfm['total_score'] = rfm[['r_score','f_score','m_score']].sum(axis=1)