我有一个代表客户订单的数据框,其中有许多列,其中两个是' user_id'和'美元'。
例如:
user_id dollar
0 1 0.34592 5
1 1 0.02857 7
2 1 0.26672 6
3 1 0.34592 5
4 1 0.02857 9
5 1 0.26672 10
6 1 0.34592 6
[...]
7 40 0.02857 20
8 40 0.26672 19
9 40 0.34592 8
10 40 0.02857 18
11 40 0.26672 26
我希望将美元价值相对于每个用户行中的其他值进行标准化。我想要上一个例子的以下结果:
user_id dollar norm_dollar
0 1 0.34592 5 -1.02774024
1 1 0.02857 7 0.07905694
2 1 0.26672 6 -0.47434165
3 1 0.34592 5 -1.02774024
4 1 0.02857 9 1.18585412
5 1 0.26672 10 1.73925271
6 1 0.34592 6 -0.47434165
[...]
7 40 0.02857 20 0.7787612
8 40 0.26672 19 0.57109154
9 40 0.34592 8 -1.71327463
10 40 0.02857 18 0.36342189
编辑:
我希望每个用户单独归一化每个结果,而不是整列的值,因此例如对于user2,[20,19,8,18]应该归一化,好像均值是平均值user2 order,这里的平均值是16,25,而不是整个dataframe列的平均值。
我知道如何与一位用户合作:
user1 = data.loc[data['user_id']==1]
data.loc[data['user_id']==1]['norm_dollar'] = sp.stats.mstats.zscore(user1['dollar'])
我试图以这种方式为所有用户这样做:
data.dollar.div(sp.stats.mstats.zscore(data.groupby('user_id').dollar))
但是我收到了错误,你对如何继续有任何想法吗?
谢谢
答案 0 :(得分:1)
执行此操作的不同方法 - 例如将groupby
数据框加入原始数据框 - 但我开始喜欢使用transform
这样的内容。
语法仍然很冗长,但我认为它比join方法更具可读性。
df['norm_dollar'] = (df['dollar']
- df.groupby('user_id')['dollar'].transform(np.mean)) \
/ df.groupby('user_id')['dollar'].transform(np.std)
如果您需要在np.std
上指定自由度,可以将其转换为
lambda x: np.std(x, ddof=n)
答案 1 :(得分:1)
那应该适合你:
def apply_zscores(x):
x['norm_dollar'] = zscore(x['dollar'])
return x
df = df.groupby('id').apply(lambda x: apply_zscores(x))