Python 中分组数据的累积自定义函数
Cumulative custom function over grouped data in Python
我希望在 pandas DataFrame 上创建一个保留函数,它在数据的分组部分上运行累积函数。
我想做一些类似于 R plyr 包所做的事情
假设我现在有一些虚拟数据:
df = pd.DataFrame({'x' : np.repeat(np.arange(1,11), 5),
'y': np.tile(np.arange(1,6), 10)} )
这给了我们(仅显示前 10 行):
x y
0 1 1
1 1 2
2 1 3
3 1 4
4 1 5
5 2 1
6 2 2
7 2 3
8 2 4
9 2 5
在这种情况下,'x' 是我要分组的列,'y' 是我要运行函数的列。
该函数是一个保留函数,它将一些因子应用于先前的总和并将其添加到当前值。在代码形式中,函数应该是这样的(可能是更好的方法):
def retention(x, r):
n = len(x)
D = np.zeros(n)
D[0] = x[0]
for i in range(1,n):
D[i] = r*D[i - 1] +x[i]
return D
但是我想在新的 'x' 值的开头重新开始。
结果应如下所示:
x y
0 1 1
1 1 2.25
2 1 3.5625
3 1 4.890625
4 1 6.22265625
5 2 1
6 2 2.25
7 2 3.5625
8 2 4.890625
9 2 6.22265625
我需要足够灵活的解决方案,以便我可以按任意数量的列进行分组,并且组的长度可变。
我尝试了多种方法都无法得到解决方案。
例如,这不有效:
grouped = df.groupby('x')
grouped.apply(lambda x: retention(df['y'],.25))
注意:在使用 plyr 包之前,我已经在 R 中完成了此操作:
retention = function(x , r) {
n =length(x)
D = rep(0, n)
D[1] = x[1]
for (i in 2:n) {
D[i]=r*D[i-1] + x[i]
}
return(D)
}
x = rep(1:10, each = 5)
y = rep(1:5, 10)
df = data.frame(x,y)
ddply(df, .(x), summarize, y = retention (y, .25))
有趣的问题。
看起来你的衰减因子,如果这样称呼的话,是 0.25,下面的两个步骤是预期的(打印前 10 个观察结果,结果称为 z
):
In [67]:
z = df.groupby('x').y.apply(lambda x: np.convolve(x, np.power(0.25, range(len(x)))[:len(x)], mode='full')[:len(x)])
print z
x
1 [1.0, 2.25, 3.5625, 4.890625, 6.22265625]
2 [1.0, 2.25, 3.5625, 4.890625, 6.22265625]
3 [1.0, 2.25, 3.5625, 4.890625, 6.22265625]
4 [1.0, 2.25, 3.5625, 4.890625, 6.22265625]
5 [1.0, 2.25, 3.5625, 4.890625, 6.22265625]
6 [1.0, 2.25, 3.5625, 4.890625, 6.22265625]
7 [1.0, 2.25, 3.5625, 4.890625, 6.22265625]
8 [1.0, 2.25, 3.5625, 4.890625, 6.22265625]
9 [1.0, 2.25, 3.5625, 4.890625, 6.22265625]
10 [1.0, 2.25, 3.5625, 4.890625, 6.22265625]
Name: y, dtype: object
In [68]:
print pd.concat([pd.DataFrame({'x': i, 'z': v}) for i, v in zip(z.index.values, z.values)]).head(10)
x z
0 1 1.000000
1 1 2.250000
2 1 3.562500
3 1 4.890625
4 1 6.222656
0 2 1.000000
1 2 2.250000
2 2 3.562500
3 2 4.890625
4 2 6.222656
基本上,累加运算(带有一个因子)是使用numpy.convolve
完成的。剩下的很简单:只需 groupby
将数据分组,应用 convolve
,然后 concat
将结果放在一起。
我希望在 pandas DataFrame 上创建一个保留函数,它在数据的分组部分上运行累积函数。
我想做一些类似于 R plyr 包所做的事情
假设我现在有一些虚拟数据:
df = pd.DataFrame({'x' : np.repeat(np.arange(1,11), 5),
'y': np.tile(np.arange(1,6), 10)} )
这给了我们(仅显示前 10 行):
x y
0 1 1
1 1 2
2 1 3
3 1 4
4 1 5
5 2 1
6 2 2
7 2 3
8 2 4
9 2 5
在这种情况下,'x' 是我要分组的列,'y' 是我要运行函数的列。
该函数是一个保留函数,它将一些因子应用于先前的总和并将其添加到当前值。在代码形式中,函数应该是这样的(可能是更好的方法):
def retention(x, r):
n = len(x)
D = np.zeros(n)
D[0] = x[0]
for i in range(1,n):
D[i] = r*D[i - 1] +x[i]
return D
但是我想在新的 'x' 值的开头重新开始。
结果应如下所示:
x y
0 1 1
1 1 2.25
2 1 3.5625
3 1 4.890625
4 1 6.22265625
5 2 1
6 2 2.25
7 2 3.5625
8 2 4.890625
9 2 6.22265625
我需要足够灵活的解决方案,以便我可以按任意数量的列进行分组,并且组的长度可变。
我尝试了多种方法都无法得到解决方案。
例如,这不有效:
grouped = df.groupby('x')
grouped.apply(lambda x: retention(df['y'],.25))
注意:在使用 plyr 包之前,我已经在 R 中完成了此操作:
retention = function(x , r) {
n =length(x)
D = rep(0, n)
D[1] = x[1]
for (i in 2:n) {
D[i]=r*D[i-1] + x[i]
}
return(D)
}
x = rep(1:10, each = 5)
y = rep(1:5, 10)
df = data.frame(x,y)
ddply(df, .(x), summarize, y = retention (y, .25))
有趣的问题。
看起来你的衰减因子,如果这样称呼的话,是 0.25,下面的两个步骤是预期的(打印前 10 个观察结果,结果称为 z
):
In [67]:
z = df.groupby('x').y.apply(lambda x: np.convolve(x, np.power(0.25, range(len(x)))[:len(x)], mode='full')[:len(x)])
print z
x
1 [1.0, 2.25, 3.5625, 4.890625, 6.22265625]
2 [1.0, 2.25, 3.5625, 4.890625, 6.22265625]
3 [1.0, 2.25, 3.5625, 4.890625, 6.22265625]
4 [1.0, 2.25, 3.5625, 4.890625, 6.22265625]
5 [1.0, 2.25, 3.5625, 4.890625, 6.22265625]
6 [1.0, 2.25, 3.5625, 4.890625, 6.22265625]
7 [1.0, 2.25, 3.5625, 4.890625, 6.22265625]
8 [1.0, 2.25, 3.5625, 4.890625, 6.22265625]
9 [1.0, 2.25, 3.5625, 4.890625, 6.22265625]
10 [1.0, 2.25, 3.5625, 4.890625, 6.22265625]
Name: y, dtype: object
In [68]:
print pd.concat([pd.DataFrame({'x': i, 'z': v}) for i, v in zip(z.index.values, z.values)]).head(10)
x z
0 1 1.000000
1 1 2.250000
2 1 3.562500
3 1 4.890625
4 1 6.222656
0 2 1.000000
1 2 2.250000
2 2 3.562500
3 2 4.890625
4 2 6.222656
基本上,累加运算(带有一个因子)是使用numpy.convolve
完成的。剩下的很简单:只需 groupby
将数据分组,应用 convolve
,然后 concat
将结果放在一起。