我有一些已识别的用户(id)在某些时间点使用服务。 我正在尝试计算每天某种服务类型的用户比例。在这个示例数据中,我只有一天,但是如果有更多的日子,我想允许代码以相同的方式工作。
day1 =
datetime_idx type id
2016-03-01 05:04:00 C 1
2016-03-01 05:24:00 A 2
2016-03-01 05:29:00 C 3
2016-03-01 05:29:00 B 4
2016-03-01 05:35:00 D 1
day1_usage = day1.groupby('type').resample('D')['id'].nunique().reset_index()
这给了我以下内容:
type datetime_idx id
0 A 2016-03-01 1
1 B 2016-03-01 1
2 C 2016-03-01 2
3 D 2016-03-01 1
我尝试以这种方式获得比例:
day1_usage['ratio'] = (day1_usage.groupby(['type','datetime_idx'])['id'].transform(sum) / day1_usage.groupby('datetime_idx')['id'].transform(sum))
这是我得到的输出:
type datetime_idx id ratio
0 A 2016-03-01 1 0.2
1 B 2016-03-01 1 0.2
2 C 2016-03-01 2 0.4
3 D 2016-03-01 1 0.2
但我想要获得的输出是:
type datetime_idx id ratio
0 A 2016-03-01 1 0.25
1 B 2016-03-01 1 0.25
2 C 2016-03-01 2 0.5
3 D 2016-03-01 1 0.25
我的代码除以用户条目的总和,但我希望它除以唯一用户的数量。
答案 0 :(得分:2)
您似乎需要size
:
day1_usage['ratio'] = (day1_usage.groupby(['type','datetime_idx'])['id'].transform(sum) /
day1_usage.groupby('datetime_idx')['id'].transform('size'))
print (day1_usage)
type datetime_idx id ratio
0 A 2016-03-01 1 0.25
1 B 2016-03-01 1 0.25
2 C 2016-03-01 2 0.50
3 D 2016-03-01 1 0.25
答案 1 :(得分:2)
import pandas as pd
import numpy as np
from io import StringIO
让我们尝试多天
csv_file = StringIO("""datetime_idx type id
2016-03-01 05:04:00 C 1
2016-03-01 05:24:00 A 2
2016-03-01 05:29:00 C 3
2016-03-01 05:29:00 B 4
2016-03-01 05:35:00 D 1
2016-03-03 05:04:00 C 1
2016-03-03 05:24:00 A 2
2016-03-03 05:29:00 C 3
2016-03-03 05:29:00 B 4
2016-03-03 05:35:00 D 1""")
days = pd.read_csv(csv_file,sep='\s\s+')
days['datetime_idx'] = pd.to_datetime(days.datetime_idx)
days = days.set_index('datetime_idx')
print(days)
type id
datetime_idx
2016-03-01 05:04:00 C 1
2016-03-01 05:24:00 A 2
2016-03-01 05:29:00 C 3
2016-03-01 05:29:00 B 4
2016-03-01 05:35:00 D 1
2016-03-03 05:04:00 C 1
2016-03-03 05:24:00 A 2
2016-03-03 05:29:00 C 3
2016-03-03 05:29:00 B 4
2016-03-03 05:35:00 D 1
days_usage = days.groupby('type').resample('D')['id'].nunique().to_frame()
days_usage
id
type datetime_idx
A 2016-03-01 1
2016-03-02 0
2016-03-03 1
B 2016-03-01 1
2016-03-02 0
2016-03-03 1
C 2016-03-01 2
2016-03-02 0
2016-03-03 2
D 2016-03-01 1
2016-03-02 0
2016-03-03 1
days_usage['ratio'] = (days_usage.unstack(0)
.div(days.resample('D')['id'].nunique(), axis='index')).fillna(0).stack().swaplevel(0,1)
print(days_usage)
输出:
id ratio
type datetime_idx
A 2016-03-01 1 0.25
2016-03-02 0 0.00
2016-03-03 1 0.25
B 2016-03-01 1 0.25
2016-03-02 0 0.00
2016-03-03 1 0.25
C 2016-03-01 2 0.50
2016-03-02 0 0.00
2016-03-03 2 0.50
D 2016-03-01 1 0.25
2016-03-02 0 0.00
2016-03-03 1 0.25
答案 2 :(得分:1)
由于您已经计算了day1_usage
DataFrame,因此计算也可以像以下一样简单:
day1_usage['ratio'] = day1_usage.id / day1.id.nunique()
结果:
type datetime_idx id ratio
0 A 2016-03-01 1 0.25
1 B 2016-03-01 1 0.25
2 C 2016-03-01 2 0.50
3 D 2016-03-01 1 0.25