2016-06-04 8 views
3

처음으로 질문을하는이 사이트의 오랜 사용자입니다! 나이 :python pandas : df.apply에 데이터 프레임 전달

내가 최근에 이상적 df.apply을 사용하고 있습니다에 대한 질문에 대답 한 자비로운 모든 사용자에 힘 입어과 같이 뭔가를 찾기 위해 args 매개 변수에 dataframe를 전달하려는 : df.apply(testFunc, args=(dfOther), axis = 1)

내 궁극적 인 목표는 args 매개 변수를 전달하는 데이터 프레임을 반복하고 원래 데이터 프레임의 각 행 (예 : df)에 대해 논리를 확인하고 dfOther에서 일부 값을 반환하는 것입니다. 그래서 나는이 같은 함수가 있다고 가정 : 그러나

ValueError: The truth value of a DataFrame is ambiguous. 
Use a.empty, a.bool(), a.item(), a.any() or a.all(). 

I 전에 :

def testFunc(row, dfOther): 
    for index, rowOther in dfOther.iterrows(): 
     if row['A'] == rowOther[0] and row['B'] == rowOther[1]: 
      return dfOther.at[index, 'C'] 

df['OTHER'] = df.apply(testFunc, args=(dfOther), axis = 1) 

나의 현재 이해 args이 시리즈 개체를 기대하는, 그리고이 사실은 우리가 다음과 같은 오류가이 실행 그렇다면 단일 데이터 프레임으로 만 전달되는 testFunc을 작성했습니다. 실제로는 다음과 같이 작성된 priorTestFunc을 작성했습니다 ... 그리고 작동합니다! 그래서

def priorTestFunc(row, dfOne, dfTwo): 
    for index, rowOne in dfOne.iterrows(): 
     if row['A'] == rowOne[0] and row['B'] == rowOne[1]: 
      return dfTwo.at[index, 'C'] 

df['OTHER'] = df.apply(testFunc, args=(dfOne, dfTwo), axis = 1) 

내 당황 그래서 같은 testFunc를 작성하는 습관을오고 있고 의도 한대로 일하고있다 : 누군가가 나에게 이유를 알려 수 있다면

def testFunc(row, dfOther, _): 
    for index, rowOther in dfOther.iterrows(): 
     if row['A'] == rowOther[0] and row['B'] == rowOther[1]: 
      return dfOther.at[index, 'C'] 

df['OTHER'] = df.apply(testFunc, args=(dfOther, _), axis = 1) 

는 정말 감사하겠습니다 이런 종류의 문제를 해결하기 위해 내가 어쩔지도 모르는 오류와 아마도 어쩌면 다른 대안이 될 것입니다 !!

EDIT : 요청한대로 : 내 dfs는 일반적으로 아래처럼 보입니다. 두 개의 일치하는 열이 있고 dfOther.at[index, column]에서 값을 반환합니다. pd.concat([dfOther, df])을 고려했지만 알고리즘 테스트 조건을 실행합니다. df 그리고 dfOther (업데이트 예정)의 특정 값에서 적절히 업데이트하면 df이 비교적 깔끔하고 멀티 인덱스를 만들고 그에 대한 모든 것을 던지기를 원합니다. 또한 나는 df.iterrows이 일반적으로 느리다는 것을 알고 있습니다. 그러나이 데이터 프레임은 최대 500 행이 될 것이므로 확장 성은 현재 저에게 큰 관심사가 아닙니다.

df 
Out[10]: 
    A B  C 
0 foo bur 6000 
1 foo bur 7000 
2 foo bur 8000 
3 bar kek 9000 
4 bar kek 10000 
5 bar kek 11000 

dfOther 
Out[12]: 
    A B  C 
0 foo bur 1000 
1 foo bur 2000 
2 foo bur 3000 
3 bar kek 4000 
4 bar kek 5000 
5 bar kek 6000 

답변

3

에러이 일치한다 : 여기

File "C:\Anaconda3\envs\p2\lib\site-packages\pandas\core\frame.py", line 4017, in apply 
    if kwds or args and not isinstance(func, np.ufunc): 

, if kwds or args은 그것이 반복 가능한인지 확인하는 일반적인 방법이다 apply에 전달 args의 길이가 0보다 큰지 여부를 검사한다 빈 :

l = [] 

if l: 
    print("l is not empty!") 
else: 
    print("l is empty!") 

l is empty!

l = [1] 

if l: 
    print("l is not empty!") 
else: 
    print("l is empty!") 

df.apply에 튜플을 args으로 전달한 경우 True를 반환하므로 문제가 발생하지 않습니다.그러나, 파이썬은 튜플 (DF)를 해석하지 않습니다

type((df)) 
Out[39]: pandas.core.frame.DataFrame 

그것은 괄호 안에 단지 DataFrame/변수입니다. if df을 입력하면

if df: 
    print("df is not empty") 

Traceback (most recent call last): 

    File "<ipython-input-40-c86da5a5f1ee>", line 1, in <module> 
    if df: 

    File "C:\Anaconda3\envs\p2\lib\site-packages\pandas\core\generic.py", line 887, in __nonzero__ 
    .format(self.__class__.__name__)) 

ValueError: The truth value of a DataFrame is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all(). 

같은 오류 메시지가 나타납니다. 당신이 it'a 튜플을 표시하기 위해 쉼표를 사용하는 경우, 그것을 잘 작동합니다 : 결과

if (df,): 
    print("tuple is not empty") 

tuple is not empty 

를, 그것은 singleton 문제를 해결해야함으로써 args=(dfOther)에 쉼표를 추가.

df['OTHER'] = df.apply(testFunc, args=(dfOther,), axis = 1) 
+1

@macavich, spot on! 그것은 좋은 캐치! – MaxU

+0

잘 설명하고 우아한 대답에 대한 @ayhan 감사합니다. – macavich

+0

@macavich, [accepting] (http://meta.stackexchange.com/a/5235)이 가장 도움이되는 대답이라고 생각해보십시오 - 질문에 답변했음을 나타냅니다 – MaxU

관련 문제