2014-07-10 2 views
1

일부 계산 결과를 나타내는 열을 추가하고 싶습니다 (복잡한 경우). 각 그룹 및 각 행에서 계산을 수행해야합니다 값은 그 위의 행에 따라 다릅니다.python pandas : groupby apply 함수는 이전 행을 봅니다.

편집 한 그래서 난 어쩌면 내가이 작품을 어떻게 적용되는지 이해하고 있지 않다, 아래에있는 내 코드를 업데이트했지만, 나는이 실행 것이라고 생각 : 여기에 지금까지 가지고있는 코드와 원하는 출력의 간단한 예입니다 두 번 (각 그룹당 한 번). 그런 다음 내 함수는 해당 실행 내에서 각 행을 반복합니다. 나는 그것이 왜 3 번이나가는 지에 대해서 여전히 의아해하고 있습니다 ... 나는 "실행 된"것이 5 번 인쇄 될 것이라고 생각했습니다. 이것에 대한 생각?

편집 2 나는 내 반환 함수에 들여 쓰기가 잘못되었습니다. 그것은 그것을 고쳤다. 도와 주셔서 감사합니다!

import pandas as pd 

df = pd.DataFrame({'type' : ['foo', 'foo', 'foo', 'bar','bar'], 'cost' : [1, 4, 2, 8,9]}) 
df['class'] = np.nan 

def customFunction(test_df): 
    print np.shape(test_df) 
    iteration = 1 
    for currRow in test_df.iterrows(): 
     print 'executed' 
     if iteration == 1: 
      test_df['class'] = 'first' 
     else: 
      if currRow[1]['cost'] > priorCost: 
       test_df['class'] = 'greater' 
      elif currRow[1]['cost'] < priorCost: 
       test_df['class'] = 'less' 
      else: 
       test_df['class'] = 'equal' 

     iteration += 1   
     priorCost = currRow[1]['cost'] 

    return test_df 

grouped_df = df.groupby(['type']).apply(customFunction) 

출력 :

(2, 2) 
executed 
(2, 2) 
executed 
(3, 2) 
executed 
    cost type class 
0  1 foo first 
1  4 foo first 
2  2 foo first 
3  8 bar first 
4  9 bar first 

답변

2

나는 내가 지금까지 가지고로까지 당신을 줄 것이다 - 내가 지금 짧은 휴식이 필요하지만, :

df = pd.DataFrame(pd.read_clipboard()) 
df.set_index('type', inplace=True) 
test = df.groupby(level=0).apply(lambda x: x.cost.diff()) 

이후 (저를 준다 diff()은 첫 번째 항목에서 열 내의 차이를 계산합니다.

Out[160]: 
type 
bar  type 
bar NaN 
bar  1 
Name: cost, dtype: ... 
foo  type 
foo NaN 
foo  3 
foo  -2 
Name: co... 
dtype: object 

여기에는 필요한 모든 정보가 들어 있습니다. 현재이 정보를 원본 데이터 프레임과 다시 병합하려고합니다. df['differences'] = test 거대한 혼란을줍니다.

업데이트 내가 거의 다 해요

는 :

>>> df['differences'] = test[1].append(test[0]) 
>>> df.loc[df['differences'] > 0, 'inWords'] = 'greater' 
>>> df.loc[df['differences'] < 0, 'inWords'] = 'lesser' 
>>> df.loc[df['differences'].isnull(), 'inWords'] = 'first' 
>>> df 
Out[184]: 
     cost differences inWords 
type        
foo  1   NaN first 
foo  4   3 greater 
foo  2   -2 lesser 
bar  8   NaN first 
bar  9   1 greater 

그래서, 필요한 유일한 것은 대신 test[1].append(test[0])의 일반적인 표현이다. 아마도 다른 사람이 칩을 칩에 넣을 수 있을까요?

업데이트 2

귀하의 코멘트에 응답 : 당신이 apply()에 대한 귀하의 함수를 정의 할 때마다, 당신은 모든 표준 팬더의 기능과 기능 내부 전체 그룹에 액세스 할 수

def compareSomethingWithinAGroup(group): 
    someMagicHappens() 
    return someValues 

한다. 그러면 복잡한 행 의존 마법을 만들 수 있습니다. 주의해야 할 유일한 것 : Series 또는 dataframe이 있어야하며 한 열만 있으면 group 행만큼 많은 항목이 있어야합니다. 그러한 someValues을 반환하는 한 항상 df['resultOfSomethingComplicated'] = df.groupby(level=0).apply(compareSomethingWithinAGroup)을 수행하고 응답의 모든 행을 사용할 수 있습니다.

+0

도와 주셔서 감사합니다. 그러나 실제로 수행하고있는 계산은 다르며 훨씬 더 복잡합니다. (예를 들어 방금 게시했습니다. 행 x-1에 상대적인 행 x를 계산할 수 있다면,이를 변환 할 수 있습니다. 내가 실제로해야 할 일). 위의 예제에서 실제 단계가 아니라 행을 비교하는 방법을 알아야합니다. – flyingmeatball

+0

내 답변을 업데이트했습니다. 희망이 도움이 될까요?그렇지 않으면,'apply()'함수 안에서 무엇이 일어나야하는지 구체적으로 도움이 필요하다면, 정확히 무엇을하려고하는지에 대해 더 구체적으로 설명 할 필요가있다. – FooBar

+0

감사합니다. 위 코드를 업데이트했는데 결과가 예상과 다른 이유를 아직 완전히 이해하지 못하고 있습니다 ... – flyingmeatball

관련 문제