如何按颜色分组计算每日用户数相对首日比值并生成新列?
计算各颜色当日用户数与首日用户数的比值
我来帮你搞定这个需求!你已经走对了第一步,但其实咱们不用单独提取最小日期,直接关联到对应的首日用户数会更高效。下面是完整的实现步骤,一步步来:
1. 先把原始数据转成DataFrame(如果还没做的话)
首先得把你那组字典数据转换成Pandas的DataFrame,方便后续操作:
import pandas as pd raw_data = [ {'date': '2020-01-01', 'color': 'blue', 'users': 100}, {'date': '2020-01-02', 'color': 'blue', 'users': 102}, {'date': '2020-01-03', 'color': 'blue', 'users': 104}, {'date': '2020-01-04', 'color': 'blue', 'users': 98}, {'date': '2020-01-02', 'color': 'red', 'users': 100}, {'date': '2020-01-03', 'color': 'red', 'users': 107}, {'date': '2020-01-04', 'color': 'red', 'users': 114}, {'date': '2020-01-05', 'color': 'red', 'users': 150}, ] df = pd.DataFrame(raw_data)
2. 给每行匹配对应颜色的首日用户数
这里有两种实用方法,选你顺手的来:
方法一:用transform一步到位(推荐)
这个方法能直接给原DataFrame的每一行添加上对应颜色的首日用户数,不用额外合并操作:
# 先把date列转成datetime类型,确保日期排序和比较是正确的(字符串日期容易出问题) df['date'] = pd.to_datetime(df['date']) # 按颜色分组,找到每组最早日期对应的users值,并用transform广播到每一行 df['first_day_users'] = df.groupby('color').apply( lambda group: group['users'].loc[group['date'] == group['date'].min()].iloc[0] ).reset_index(drop=True)
或者更简洁的写法,用idxmin定位首日的行索引:
df['first_day_users'] = df.groupby('color')['users'].transform( lambda x: x.loc[x.index[df.loc[x.index, 'date'].idxmin()]] )
方法二:分步构建映射表再合并
如果你习惯分步操作,先做一个颜色和首日用户的对应表,再合并到原数据里:
# 按颜色分组,提取每个组最早日期对应的users值 first_day_map = df.groupby('color').apply( lambda g: g[g['date'] == g['date'].min()]['users'].iloc[0] ).reset_index(name='first_day_users') # 把映射表合并到原DataFrame df = df.merge(first_day_map, on='color', how='left')
3. 计算比值列
有了首日用户数,直接做除法就能得到想要的比值了:
df['users_ratio'] = df['users'] / df['first_day_users']
最终效果
运行完上面的代码后,你的DataFrame会变成这样(截取部分示例):
| date | color | users | first_day_users | users_ratio |
|---|---|---|---|---|
| 2020-01-01 | blue | 100 | 100 | 1.00 |
| 2020-01-02 | blue | 102 | 100 | 1.02 |
| 2020-01-02 | red | 100 | 100 | 1.00 |
| 2020-01-03 | red | 107 | 100 | 1.07 |
关键点提醒
- 一定要转日期类型:如果
date是字符串格式,直接比较大小会出错(比如"2020-10-01"字符串比"2020-01-02"小,但实际日期更晚),转成datetime类型才能保证日期判断准确。 transform是Pandas分组操作里的神器,能把分组计算的结果直接对应到原数据的每一行,省去合并的麻烦。
内容的提问来源于stack exchange,提问作者MM55
相关产品推荐
相关产品推荐

