如何绘制指定区间的直方图?基于Pandas分析广告触达与到店率
解决方法
1. 数据预处理与分组统计
首先需要筛选目标线路数据,统计每个用户标识(uid)的触达次数和到店情况,再按要求的触达次数区间分组,计算每组的到店率:
import pandas as pd import numpy as np import random import matplotlib.pyplot as plt # 生成原始数据(与你的代码一致) items1 = ['one', 'two'] items2 = ['JR Sagami Line','JR Tsurumi Line','JR Sagami Line','JR Tsurumi Line','JR Ome Line'] items3 = ['tokyo','shizuoka','saitma','oosaka'] dict_a = { 'log_timestamp_jst': np.random.randint(100, size=100), 'dt': pd.date_range('2022-5-01', periods=100, freq='1d'), 'hh': np.random.randint(10, 21, size=100), 'uid': np.random.choice(30, 100, replace=True), 'uid_type': random.choices(items1, k=100), 'brand_id': random.choices(items2, k=100), 'state': random.choices(items3, k=100), 'shop_name': pd.util.testing.rands_array(8, size=100), 'shop_state': random.choices(items3, k=100), 'visit_or_not':np.random.randint(2, size=100), 'time_at_shop': np.random.randint(21, size=100) } df = pd.DataFrame(dict_a) # 筛选目标线路数据 line_df = df[df['brand_id'] == 'JR Tsurumi Line'] # 按uid分组,统计每个uid的触达次数和是否有过到店记录 uid_stats = line_df.groupby('uid').agg( reach_count=('uid', 'count'), has_visited=('visit_or_not', lambda x: 1 if x.any() else 0) ).reset_index() # 定义触达次数分组规则 def group_reach(count): if count == 0: return '0' elif 1 <= count <= 2: return '0-2' else: return '3以上' # 为已有触达记录的uid分配分组 uid_stats['reach_group'] = uid_stats['reach_count'].apply(group_reach) # 补充"0次触达"的统计(总uid数为30,减去已触达的数量即为未触达数) total_uids = 30 reached_uids = uid_stats['uid'].nunique() unreached_data = pd.DataFrame({ 'reach_group': ['0'], 'total_uids': [total_uids - reached_uids], 'visited_uids': [0] }) # 统计每组的总uid数和到店uid数 group_stats = uid_stats.groupby('reach_group').agg( total_uids=('uid', 'nunique'), visited_uids=('has_visited', 'sum') ).reset_index() # 合并未触达数据并计算到店率 group_stats = pd.concat([group_stats, unreached_data], ignore_index=True) group_stats['visit_rate'] = group_stats['visited_uids'] / group_stats['total_uids'] group_stats['visit_rate'] = group_stats['visit_rate'].fillna(0)
2. 绘制目标图表
基于分组后的统计数据,绘制柱状图展示触达次数区间与到店率的关系:
# 设置图表样式 plt.style.use('seaborn-v0_8') # 绘制柱状图 ax = group_stats.plot(kind='bar', x='reach_group', y='visit_rate', figsize=(8, 5), color='#1f77b4', legend=False) # 设置轴标签与标题 ax.set_xlabel('广告触达次数') ax.set_ylabel('到店率') ax.set_title('JR Tsurumi Line 广告触达次数与到店率关联') # 将Y轴刻度转换为百分比格式 ax.yaxis.set_major_formatter(plt.FuncFormatter(lambda x, pos: f'{x*100:.1f}%')) # 调整X轴标签角度,避免重叠 plt.xticks(rotation=0) # 在柱子上方添加数值标签 for p in ax.patches: height = p.get_height() ax.text(p.get_x() + p.get_width()/2., height, f'{height*100:.1f}%', ha='center', va='bottom') plt.tight_layout() plt.show()
原代码问题说明
你之前的代码line.uid.value_counts().plot(kind="bar")仅统计了每个uid的触达次数并绘制柱状图,既没有关联到店率数据,也没有对触达次数进行区间分组,因此无法得到你需要的结果。
内容的提问来源于stack exchange,提问作者アルサ
相关产品推荐
相关产品推荐

