2013-11-04 2 views
4

함수에 여러 인수가있는 경우 groupby.apply 또는 groupby.transform과 함께 사용할 함수를 작성하면 groupby의 일부로 함수를 호출 할 때 인수는 괄호 안의. 예를 들면 다음과 같습니다.Groupby를 사용할 때 여러 인수가있는 함수 호출

def Transfunc(df, arg1, arg2, arg2): 
    return something 

GroupedData.transform(Transfunc, arg1, arg2, arg3) 

여기서 첫 번째 인수로 df 인수가 자동으로 전달됩니다.

그러나 데이터를 그룹화하는 기능을 사용할 때 동일한 구문이 가능하지는 않습니다. 다음 예제를보십시오 :

people = DataFrame(np.random.randn(5, 5), columns=['a', 'b', 'c', 'd', 'e'], index=['Joe', 'Steve', 'Wes', 'Jim', 'Travis']) 
people.ix[2:3, ['b', 'c']] = NA 

def MeanPosition(Ind, df, Column): 
    if df[Column][Ind] >= np.mean(df[Column]): 
     return 'Greater Group' 
    else: 
     return 'Lesser Group' 
# This function compares each data point in column 'a' to the mean of column 'a' and return a group name based on whether it is greater than or less than the mean 

people.groupby(lambda x: MeanPosition(x, people, 'a')).mean() 

위의 작업은 정상적으로 작동하지만 왜 나는 람다에서 함수를 랩해야하는지 이해할 수 없습니다. 함께 사용되는 구문에 근거하여 변환하고 다음이 잘 작동한다는 것을 나에게 보인다 적용 : 왜

people.groupby(MeanPosition, people, 'a').mean() 

아무도 말해 줄 수, 또는 어떻게 람다에 포장하지 않고 함수를 호출 할 수 있습니다?

감사

편집 : 나는이 그룹에 람다에서 해당 기능을 포장하지 않고 키와 같은 기능을 전달하여 데이터 가능하다고 생각하지 않습니다. 한 가지 가능한 해결 방법은 함수를 키로 전달하는 대신 함수에 의해 생성 된 배열을 전달하는 것입니다. .... 단지 목록 comprhension 배열을 사용하여 간단하게 모두 함께 중간 남자 기능을 절단하고

+0

(당신이 당신의 예에있는 모든 별개의 그룹을 가지고 약간 수정) 원하는 무슨 생각을하는 방법입니다 (지금까지 볼 수 있듯이, 그것은 아닙니다) 그리고 미래에 groupby에게'** kwarg'를 추가 할 수 있다면 –

+0

그 좌절! 나는 그것을 람다로 감싸는 것은 쉽지만, 이것이 왜 그럴 수 있는지 설명하기는 어렵다. ... –

답변

3

합격을

def MeanPositionList(df, Column): 
    return ['Greater Group' if df[Column][row] >= np.mean(df[Column]) else 'Lesser Group' for row in df.index] 

Grouped = people.groupby(np.array(MeanPositionList(people, 'a'))) 
Grouped.mean() 

을하지만 당연히 더 좋을 수 :이 다음과 같은 방식으로 작동합니다 apply에 대한 인수는 apply이 모든 인수를 대상 함수에 전달하기 때문에 작동합니다.

그러나 groupby은 여러 개의 인수를 사용합니다 (here 참조). 따라서 인수를 구분할 수 없습니다. 람다/명명 된 함수를 전달하는 것은 더 명확하고 갈 길입니다. 여기

는 당신이 그것을 가능하다면 나는 그것을, 당신은 디자인 결정을 소스를 확인하고 볼 수 있습니다 생각

In [22]: def f(x): 
    ....:  result = Series('Greater',index=x.index) 
    ....:  result[x<x.mean()] = 'Lesser' 
    ....:  return result 
    ....: 

In [25]: df = DataFrame(np.random.randn(5, 5), columns=['a', 'b', 'c', 'd', 'e'], index=['Joe', 'Joe', 'Wes', 'Wes', 'Travis']) 

In [26]: df 
Out[26]: 
       a   b   c   d   e 
Joe -0.293926 1.006531 0.289749 -0.186993 -0.009843 
Joe -0.228721 -0.071503 0.293486 1.126972 -0.808444 
Wes  0.022887 -1.813960 1.195457 0.216040 0.287745 
Wes -1.520738 -0.303487 0.484829 1.644879 1.
Travis -0.061281 -0.517140 0.504645 -1.844633 0.683103 

In [27]: df.groupby(df.index.values).transform(f) 
Out[27]: 
       a  b  c  d  e 
Joe  Lesser Greater Lesser Lesser Greater 
Joe  Greater Lesser Greater Greater Lesser 
Travis Greater Greater Greater Greater Greater 
Wes  Greater Lesser Greater Lesser Lesser 
Wes  Lesser Greater Lesser Greater Greater 
+0

Thanks Jeff. 그것이 내가 가정 한 것입니다. 그렇지만 궁금한 점은 람다 표기법을 사용하지 않고 여러 인수가있는 위의 함수를 어떻게 전달할 수 있는가입니다. people.groupby (MeanPosition (people, 'a'))를 작성하면 불충분 한 인수가 전달되었다는 오류가 생성됩니다. 어떻게 람다 표기법을 사용하여 Ind 인수를 전달할 수 있습니까? 아니면 불가능한가요? –

+0

나는 대답을 편집했다. 그루퍼 함수는 인덱스 레이블에서 호출되기 때문에 이론상 1 개의 인수 만 받아들이므로 이론적으로는 부분 함수를 사용할 수 있습니다. 그러나 위의 방법으로 문제를 해결할 수 있다고 생각합니다. – Jeff

+0

고마워, 사실 그건 내가 찾던 것이 아니야. 내 질문을 편집했습니다. 나는 내가 할 수 있다고 생각하지 않는다 (즉, 람다에 랩핑하지 않고 그룹 기능을 호출한다). 한 가지 해결책은 그 자체로 함수에 의해 생성 된 배열 인 그룹 연산에 키를 전달하는 것입니다. –

관련 문제