Python案例教你用Pandas做数据频率统计
目录导读
- 为什么频率统计是数据分析的基石
- 准备工作:Pandas环境搭建与数据导入
- 核心方法:value_counts()的完整用法与参数解析
- 进阶场景:多维度交叉频率统计
- 实战案例:电商订单数据频率分析(附代码)
- 常见问答:解决频率统计中的10个高频问题
- 性能优化:大数据量下的统计技巧
- 从频率统计到业务洞察的完整链路
为什么频率统计是数据分析的基石
在电商、金融、社交媒体等领域的实际业务中,数据分析师每天面对的首要任务就是“了解数据分布”,频率统计(Frequency Statistics)正是回答“某个值出现了多少次”这一核心问题的技术。

- 用户最常购买的商品类别是什么?
- 一周中的哪一天订单量最高?
- 有多少客户属于“高价值”标签?
Pandas作为Python生态中最强大的数据处理库,提供了极简的语法和极高的性能来完成这些统计任务,本文将通过一个真实的电商订单数据集,手把手演示如何用Pandas进行单变量、多变量的频率统计,并解决实际工作中可能遇到的编码、性能、可视化等问题。
提示:本文所有代码均基于Python 3.8+和Pandas 1.3+,可在Jupyter Notebook或任何Python环境中运行。
准备工作:Pandas环境搭建与数据导入
确保已安装Pandas库:
pip install pandas numpy
生成模拟电商订单数据
为了贴近真实场景,我们创建一个包含日期、用户ID、商品类别、支付金额的DataFrame:
import pandas as pd
import numpy as np
# 设置随机种子保证结果可复现
np.random.seed(42)
# 生成1000条模拟订单
dates = pd.date_range('2024-01-01', periods=1000, freq='H') # 每小时一条
categories = ['电子产品', '服装', '食品', '日用品', '图书']
users = [f'U{str(i).zfill(4)}' for i in range(1, 201)] # 200个用户
df = pd.DataFrame({
'order_time': dates,
'user_id': np.random.choice(users, size=1000),
'category': np.random.choice(categories, size=1000, p=[0.3, 0.25, 0.2, 0.15, 0.1]),
'amount': np.round(np.random.uniform(10, 500, 1000), 2)
})
print(df.head())
输出示例:
order_time user_id category amount
0 2024-01-01 00:00:00 U0032 电子产品 123.45
1 2024-01-01 01:00:00 U0187 食品 67.89
2 2024-01-01 02:00:00 U0015 服装 234.56
核心方法:value_counts()的完整用法与参数解析
value_counts()是Pandas中用于频率统计的核心函数,它可以直接应用于Series(单列)或DataFrame的子列。
基础语法
df['column_name'].value_counts()
关键参数详解
| 参数 | 作用 | 示例 |
|---|---|---|
normalize |
返回频率占比(相对频率)而非计数 | value_counts(normalize=True) |
sort |
是否按频率降序排列,默认为True | value_counts(sort=False) |
ascending |
按频率升序排列 | value_counts(ascending=True) |
bins |
对连续变量分箱后统计 | value_counts(bins=5)(需数值列) |
dropna |
是否排除缺失值,默认为True | value_counts(dropna=False) |
实战演示:统计商品类别出现次数
# 基本频率统计(按降序) category_freq = df['category'].value_counts() print(category_freq) # 输出: # 电子产品 301 # 服装 252 # 食品 209 # 日用品 147 # 图书 91 # Name: category, dtype: int64 # 计算占比(百分比) category_pct = df['category'].value_counts(normalize=True).mul(100).round(1) print(category_pct) # 电子产品 30.1 # 服装 25.2 # 食品 20.9 # 日用品 14.7 # 图书 9.1
进阶场景:多维度交叉频率统计
现实业务中我们往往需要同时分析两个及以上变量的频次关系,“不同商品类别在各时间段的订单量”。
crosstab()交叉表
# 将时间转换为“上午/下午”时段
df['time_period'] = df['order_time'].dt.hour.apply(
lambda x: '上午' if 6 <= x < 12 else ('下午' if 12 <= x < 18 else '夜间')
)
# 创建交叉频率表
cross_tab = pd.crosstab(df['category'], df['time_period'])
print(cross_tab)
输出片段:
time_period 下午 上午 夜间
category
电子产品 110 96 95
服装 86 81 85
食品 70 70 69
日用品 55 42 50
图书 31 28 32
groupby() + size()
# 按多列分组统计频次 grouped_freq = df.groupby(['category', 'time_period']).size().unstack(fill_value=0) print(grouped_freq)
两种方法效果相同,crosstab()更简洁,groupby()更适合后续聚合操作。
实战案例:电商订单数据频率分析
找出高频用户(Top 10%)
# 统计每个用户的购买频次
user_freq = df['user_id'].value_counts()
# 定义Top 10%用户阈值
threshold = user_freq.quantile(0.9)
high_freq_users = user_freq[user_freq >= threshold]
print(f"高频用户数量: {len(high_freq_users)}")
print(high_freq_users.head())
按周统计订单量趋势
# 提取周数
df['week'] = df['order_time'].dt.isocalendar().week
weekly_freq = df['week'].value_counts().sort_index()
# 绘制折线图(需matplotlib)
import matplotlib.pyplot as plt
plt.figure(figsize=(12,4))
weekly_freq.plot(kind='line', marker='o')'Weekly Order Count Trend')
plt.xlabel('Week Number')
plt.ylabel('Order Count')
plt.grid(True, alpha=0.3)
plt.show()
金额分布的分箱统计
# 将金额按区间分箱(0-100,100-200,200-300,300+)
bins = [0, 100, 200, 300, float('inf')]
labels = ['低', '中低', '中高', '高']
df['amount_level'] = pd.cut(df['amount'], bins=bins, labels=labels)
amount_freq = df['amount_level'].value_counts()
print(amount_freq)
# 低 355
# 中低 327
# 中高 195
# 高 123
常见问答:解决频率统计中的10个高频问题
Q1:为什么我的value_counts()返回了NaN?
A:检查dropna参数是否设置为False,若列中包含NaN,默认会排除,如果需要统计缺失值数量,请使用value_counts(dropna=False)。
Q2:如何同时统计两个变量的频次并排序?
A:先使用groupby(['col1','col2']).size(),然后用reset_index().sort_values(0, ascending=False)。
Q3:频率统计结果能直接用于画图吗?
A:可以。value_counts()返回的是Series,可以直接用plot.bar()或plot.pie()生成图表。
Q4:如何统计DataFrame中每列的缺失值频次?
A:使用df.isnull().sum(),或配合value_counts():df['col'].isnull().value_counts()。
Q5:大数据量下value_counts()太慢怎么办?
A:见下一节“性能优化”。
Q6:怎样统计连续变量的固定区间频次?
A:使用pd.cut()进行分箱,再对结果做value_counts()。
Q7:频率占比(normalize)的精度如何控制?
A:可以用round(2)保留两位小数,或直接乘以100转换成百分比。
Q8:如何按自定义顺序显示频率结果?
A:使用reindex()方法:result.reindex(['A','B','C'])。
Q9:value_counts()能用于多级索引吗?
A:可以,但建议先用stack()或groupby()展平数据。
Q10:频率统计结果如何导出为Excel?
A:直接使用to_excel()方法:result.to_excel('output.xlsx')。
性能优化:大数据量下的统计技巧
当数据量超过100万行时,直接使用value_counts()可能造成内存压力,以下是优化建议:
-
使用Categorical类型
df['category'] = df['category'].astype('category') # 底层用整数编码,大幅减少内存 -
采样测试
sample_data = df.sample(frac=0.1) # 取10%数据先验证 sample_data['category'].value_counts()
-
使用Numpy加速
import numpy as np unique, counts = np.unique(df['category'].values, return_counts=True) freq_series = pd.Series(counts, index=unique)
-
并行计算
对于超大DataFrame,可用pandarallel库实现并行处理:from pandarallel import pandarallel pandarallel.initialize(progress_bar=False) df.parallel_apply(lambda x: x['category'].value_counts())
从频率统计到业务洞察的完整链路
本文通过电商订单数据这一真实场景,完整演示了如何用Pandas进行:
- 单变量频率统计(
value_counts) - 多变量交叉分析(
crosstab/groupby) - 时间维度频率趋势
- 数值型变量分箱统计
- 性能优化方案
频率统计绝非简单的“计数”,它是数据探索的第一步,能快速揭示数据分布规律、异常点和业务规律,建议读者在拿到任何数据集后,始终先对关键分类变量和数值变量做频率分析——这往往能直接定位到最具价值的数据洞察。
延伸思考:如果将频率统计结果与pivot_table、可视化工具、假设检验结合,你能从数据中挖掘出更多隐藏的业务模式吗?高价值用户是否更倾向在夜间下单?不同商品类别的退货率是否存在显著差异?这些问题都可以通过多维度频率统计找到答案。