2013-08-16 2 views
12

우리 팬더 사용 코드의 많은 곳에서 우리는 파이썬 함수 process(row)을 가지고 있습니다. 이 함수는 DataFrame.iterrows() 이상 사용되며 각각 row을 사용하고 일부 처리를 수행하며 최종적으로 수집하는 값을 새로운 Series으로 반환합니다.파이썬 함수로 DataFrame 행을 효율적으로 처리합니까?

이 사용 패턴은 numpy/Pandas 스택의 성능상의 이점 대부분을 회피합니다.

  1. 이 사용 패턴을 가능한 한 효율적으로 만드는 가장 좋은 방법은 무엇입니까? ?
  2. 대부분의 코드를 다시 작성하지 않고도 처리 할 수 ​​있습니까?

이 질문의 또 다른 측면은 이러한 모든 기능을 수치 효율적인 표현으로 변환 할 수 있습니까? 나는 numpy/scipy/Pandas 스택에 대해 많은 것을 배웠지 만 진정한 임의 논리에 대해서는 때때로 위와 같은 느린 순수 Python 아키텍처를 사용해야 할 수도 있습니다. 그럴까요?

+0

수학을하는 경우 벡터화 연산을 수행 할 수 있어야합니다. 문자열이나 다른 고정 크기의 데이터 유형을 사용하는 경우 숫자에 대해 vecorized 방식으로 계산 한 다음 나머지 부분에 대해 행 기반으로 수행 할 수 있습니다 ... 수행중인 작업에 대한 세부 정보를 제공 할 수 있습니까? –

답변

19

축 = 1을 따라 함수를 적용해야합니다. 질문의 두 번째 부분에 관해서는

>>> df = pd.DataFrame({'a': np.arange(3), 
         'b': np.random.rand(3)}) 
>>> df 
    a   b 
0 0 0.880075 
1 1 0.143038 
2 2 0.795188 
>>> def func(row): 
     return row['a'] + row['b'] 
>>> df.apply(func, axis=1) 
0 0.880075 
1 1.143038 
2 2.795188 
dtype: float64 

: 새로운 시리즈 개체에

df.apply(you_function, axis=1) 

예를 함수 인수로 행을 받게됩니다, 그것은 반환 아무것도 수집됩니다 행 현명한 작업을 심지어 팬더 apply을 사용하여 최적화 된 제품도 가장 빠른 해결책은 아닙니다. 그들은 확실히 많은 파이썬 루프보다 빠르지 만 가장 빠릅니다. 타이밍 작업을 통해 테스트 할 수 있으며 차이점을 확인할 수 있습니다.

일부 연산은 열 기반 연산으로 변환 될 수 있습니다 (예제에서 하나는 쉽게 df['a'] + df['b']으로 변환 될 수 있지만 다른 연산자는 쉽게 변환 할 수 없습니다). 특히 분기가 많거나 특수한 경우 또는 다른 논리를 수행해야하는 경우에 유용합니다. 이 경우 apply이 너무 느리면 "Cython-izing" 코드를 제안합니다. Cython은 NumPy C API로 정말 잘 실행되며 달성 할 수있는 최대 속도를 제공합니다.

또는 numba을 시도 할 수 있습니다. :)

+0

'applay'의 작은 오타 :) –

+0

@PhillipCloud'axis = 1'을 따라 거의 사용하지 않는 것을 보았습니다. 특정 성능상의 이유가 있습니까? 배열 행을 현명하게 반복하는 것이 가장 빠른 방법일까요? –

+0

나는 그것이 있다고 생각한다. 특별한 이유없이, 나는 단지 열 지향적 인 데이터로 작업하기 때문에 사용하지 않아도된다. (그래서 내 마음의 꼭대기에 있지 않다.) 나는 또한 일종의 재구성이나'groupby' 조작으로 대부분의 경우 행을 따라 작업을 피할 수 있다는 의혹을 가지고 있지만, 그 점을 뒷받침 할만한 증거가 없다. 여기에 잘못된 것일 수도있는 내 직감. –

관련 문제