我想为数据框添加一个列,其中每个唯一用户的移动平均值来自另一列(这里是棘手的部分)。
首先想到的是获取所有唯一用户的列表,并迭代所有这些用户获取数据框的子集,其中用户列与用户相同:
import pandas as pd
df = pd.DataFrame()
df['user'] = [1,2,3,2,2,1,1,3,3,3,3,3,3,2,1,2,1,2,1,1]
df['value'] = [3,1,5,7,2,2,2,9,8,7,6,5,4,3,2,2,2,1,2,3]
unique_users = df['user'].unique()
df['rolled_value'] = 0
for user in unique_users:
temp_df = df[df['user'] == user]
temp_df['rolled_value'] = temp_df['value'].rolling(2).mean()
它不起作用,因为它不会让我更改列的值,因为它是来自df的切片的副本,但你明白了。
这将非常慢,我有10M行,这将需要永远。
我是python的新手,无法想出快速的等价物。有什么方法可以在这里使用lambda函数吗?
任何帮助都将不胜感激。
谢谢!
答案 0 :(得分:1)
如果我理解你想做什么,以下情况应该有效:
rolled_values = df.groupby('user')['value'].rolling(2).mean().reset_index()
这会返回按用户分组的DataFrame,列为< level_1'包含旧索引和'值'列现在包含滚动平均值。
user level_1 value
0 1 0 NaN
1 1 5 2.5
2 1 6 2.0
3 1 14 2.0
4 1 16 2.0
5 1 18 2.0
6 1 19 2.5
7 2 1 NaN
8 2 3 4.0
9 2 4 4.5
(...)
现在您只需将此列添加到旧的DataFrame中:
df['rolled_values'] = rolled_values.set_index('level_1')['value']
user value rolled_values
0 1 3 NaN
1 2 1 NaN
2 3 5 NaN
3 2 7 4.0
4 2 2 4.5
(...)