2015-01-06 2 views
2

데이터의 그룹화 된 부분에 대해 누적 기능을 실행하는 pandas DataFrame에 대한 보존 함수를 만들려고합니다.Python의 그룹화 된 데이터에 누적 된 사용자 정의 함수

본인은 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)) 

답변

1

흥미로운 질문을. 당신의 붕괴 요인은, 경우에하는 것은 그래서 전화를 나타납니다 다음과 같은 두 가지 단계를 (처음 10 명 관찰 결과가 z라고 인쇄) 것입니다 무엇을, 0.25 :

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 결과를 함께 적용합니다.

+0

감사합니다. CT! 한동안 붙어 있었어. 이런 식으로하지 않아도 될거야. 아주 똑똑한 접근 –

관련 문제