[python] 여러 열을 참조하는 팬더 ‘적용’기능이 작동하지 않는 이유는 무엇입니까? [닫은]

다음 데이터 프레임에서 여러 열을 사용할 때 Pandas apply 함수에 문제가 있습니다.

df = DataFrame ({'a' : np.random.randn(6),
                 'b' : ['foo', 'bar'] * 3,
                 'c' : np.random.randn(6)})

다음 기능

def my_test(a, b):
    return a % b

이 기능을 다음과 같이 적용하려고하면 :

df['Value'] = df.apply(lambda row: my_test(row[a], row[c]), axis=1)

오류 메시지가 나타납니다.

NameError: ("global name 'a' is not defined", u'occurred at index 0')

이 메시지를 이해하지 못하고 이름을 올바르게 정의했습니다.

이 문제에 대한 도움을 주시면 감사하겠습니다.

최신 정보

당신의 도움을 주셔서 감사합니다. 실제로 코드에 구문 오류가 발생했습니다. 인덱스에 ”를 넣어야합니다. 그러나 여전히 다음과 같은보다 복잡한 기능을 사용하여 동일한 문제가 발생합니다.

def my_test(a):
    cum_diff = 0
    for ix in df.index():
        cum_diff = cum_diff + (a - df['a'][ix])
    return cum_diff 



답변

''문자열 을 잊어 버린 것 같습니다 .

In [43]: df['Value'] = df.apply(lambda row: my_test(row['a'], row['c']), axis=1)

In [44]: df
Out[44]:
                    a    b         c     Value
          0 -1.674308  foo  0.343801  0.044698
          1 -2.163236  bar -2.046438 -0.116798
          2 -0.199115  foo -0.458050 -0.199115
          3  0.918646  bar -0.007185 -0.001006
          4  1.336830  foo  0.534292  0.268245
          5  0.976844  bar -0.773630 -0.570417

BTW, 제 생각에는 다음과 같은 방식이 더 우아합니다.

In [53]: def my_test2(row):
....:     return row['a'] % row['c']
....:     

In [54]: df['Value'] = df.apply(my_test2, axis=1)


답변

계산 (열 a) % (열 b)를 계산하려면 필요하지 않습니다 apply. 직접 수행하십시오.

In [7]: df['a'] % df['c']                                                                                                                                                        
Out[7]: 
0   -1.132022                                                                                                                                                                    
1   -0.939493                                                                                                                                                                    
2    0.201931                                                                                                                                                                    
3    0.511374                                                                                                                                                                    
4   -0.694647                                                                                                                                                                    
5   -0.023486                                                                                                                                                                    
Name: a


답변

DataFrame df의 열 ‘a’와 ‘b’에 add5 함수를 적용한다고 가정 해 봅시다.

def add5(x):
    return x+5

df[['a', 'b']].apply(add5)


답변

위의 모든 제안은 효과가 있지만 계산을보다 효율적으로하려면 numpy vector 연산을 사용해야합니다 (여기에서 지적한 바와 같이) .

import pandas as pd
import numpy as np


df = pd.DataFrame ({'a' : np.random.randn(6),
             'b' : ['foo', 'bar'] * 3,
             'c' : np.random.randn(6)})

예제 1 : 다음으로 반복 pandas.apply():

%%timeit
def my_test2(row):
    return row['a'] % row['c']

df['Value'] = df.apply(my_test2, axis=1)

가장 느린 실행은 가장 빠른 실행보다 7.49 배 길었습니다. 이는 중간 결과가 캐시되고 있음을 의미 할 수 있습니다. 1000 루프, 루프 당 최고 3 : 481 µs

예제 2 : 다음을 사용하여 벡터화 pandas.apply():

%%timeit
df['a'] % df['c']

가장 느린 실행은 가장 빠른 실행보다 458.85 배 길었습니다. 이는 중간 결과가 캐시되고 있음을 의미 할 수 있습니다. 10000 루프, 루프 당 최고 3 : 70.9 µs

예제 3 : numpy 배열을 사용하여 벡터화 :

%%timeit
df['a'].values % df['c'].values

가장 느린 실행은 가장 빠른 실행보다 7.98 배 길었습니다. 이는 중간 결과가 캐시되고 있음을 의미 할 수 있습니다. 100000 루프, 루프 당 최고 3 : 6.39 µs

따라서 numpy 배열을 사용하여 벡터화하면 속도가 거의 2 배 향상되었습니다.


답변

이것은 이전 솔루션과 동일하지만 df.apply 자체에서 함수를 정의했습니다.

df['Value'] = df.apply(lambda row: row['a']%row['c'], axis=1)


답변

위에서 설명한 세 가지를 모두 비교했습니다.

값 사용

% timeit df [ 'value'] = df [ 'a']. values ​​% df [ 'c']. values

루프 당 139 µs ± 1.91 µs (평균 런 7 회 실행, 각 10000 루프)

값이없는

% timeit df [ 'value'] = df [ 'a'] % df [ 'c'] 

루프 당 216 µs ± 1.86 µs (평균 런 7 회 실행, 각 1000 루프)

기능 적용

% timeit df [ 'Value'] = df.apply (lambda row : row [ 'a'] % row [ 'c'], axis = 1)

루프 당 474 µs ± 5.07 µs (평균 7 번의 런, 평균 1000 루프)


답변