Pandas의 DataFrame에서 행을 반복하는 방법은 무엇입니까?
답변 :하지 마십시오 * !
팬더의 반복은 반 패턴이며 다른 모든 옵션을 다 사용한 경우에만 수행해야합니다. iter
이름에 " "가 있는 함수를 수천 행 이상 사용하지 않아야합니다. 그렇지 않으면 많은 대기 에 익숙해 져야합니다 .
DataFrame을 인쇄 하시겠습니까? 사용하십시오 DataFrame.to_string()
.
무언가를 계산하고 싶습니까? 이 경우 다음 순서로 메소드를 검색 하십시오 (여기 에서 수정 된 목록 ).
- 벡터화
- Cython 루틴
- 목록 이해 (바닐라
for
루프)
DataFrame.apply()
: i) Cython에서 수행 할 수있는 감소, ii) Python 공간에서 반복
DataFrame.itertuples()
과 iteritems()
DataFrame.iterrows()
iterrows
및 itertuples
(이 질문에 대한 답변에서 많은 득표를 모두) 등 정말 이러한 기능에 대한 유용한 유일 일련의 처리를위한 행 개체 / nametuples를 생성하는 매우 드문 경우에 사용되어야한다.
권한에
대한 이의 제기 반복에 대한 문서 페이지 에는 다음과 같은 커다란 빨간색 경고 상자가 있습니다.
팬더 객체를 반복하는 것은 일반적으로 느립니다. 많은 경우에 행을 수동으로 반복 할 필요가 없습니다 [...].
* 실제로 "하지 말 것"보다 조금 더 복잡합니다. df.iterrows()
이 질문에 대한 정답이지만 "Ops를 벡터화"하는 것이 좋습니다. 반복을 피할 수없는 상황이 있음을 인정합니다 (예 : 결과가 이전 행에 대해 계산 된 값에 의존하는 일부 작업). 그러나 라이브러리를 알고 있으면 언제인지 알아야합니다. 반복 솔루션이 필요한지 확실하지 않은 경우에는 그렇지 않을 수 있습니다. 추신 :이 답변을 작성하는 이유에 대해 더 알고 싶다면 맨 아래로 건너 뛰십시오.
많은 수의 기본 연산과 계산은 팬더 (NumPy 또는 Cythonized 함수)를 통해 "벡터화"됩니다. 여기에는 산술, 비교, (대부분) 축소, 재구성 (예 : 피벗), 조인 및 그룹 별 작업이 포함됩니다. 필수 기본 기능 에 대한 설명서 를 통해 문제에 적합한 벡터화 된 방법을 찾으십시오.
존재하지 않는 경우 사용자 정의 cython 확장을 사용하여 직접 작성하십시오 .
1) 사용 가능한 벡터화 된 솔루션이없고, 2) 성능이 중요하지만 코드를 싸이클링하는 번거 로움을 극복하기에 충분히 중요하지 않은 경우 및 3) 요소 별 변환을 수행하려는 경우 목록 이해가 다음 호출 포트가되어야합니다. 귀하의 코드에. 이 증거의 좋은 금액 이 지능형리스트가 충분히 빠른 (심지어 때로는 빨리) 많은 일반 팬더 작업에 있습니다 제안하는가.
공식은 간단합니다.
# iterating over one column - `f` is some function that processes your data
result = [f(x) for x in df['col']]
# iterating over two columns, use `zip`
result = [f(x, y) for x, y in zip(df['col1'], df['col2'])]
# iterating over multiple columns - same data type
result = [f(row[0], ..., row[n]) for row in df[['col1', ...,'coln']].to_numpy()]
# iterating over multiple columns - differing data type
result = [f(row[0], ..., row[n]) for row in zip(df['col1'], ..., df['coln'])]
비즈니스 로직을 함수로 캡슐화 할 수 있으면이를 호출하는 목록 이해를 사용할 수 있습니다. 원시 파이썬의 단순성과 속도를 통해 임의로 복잡한 작업을 수행 할 수 있습니다.
Caveats
List 이해는 데이터가 다루기 쉽다고 가정합니다. 즉, 데이터 유형이 일관되고 NaN이없는 것이지만 이것이 항상 보장되는 것은 아닙니다.
- 첫 번째 방법은 더 분명하지만 NaN을 처리 할 때는 내장 팬더 방법이 존재하는 경우를 선호하거나 (코너 케이스 처리 논리가 훨씬 우수하기 때문에) 비즈니스 논리에 적절한 NaN 처리 논리가 포함되어 있는지 확인하십시오.
- 혼합 데이터 형식을 처리 할 때는 데이터 형식이 암시 적으로 가장 일반적인 형식으로 데이터를 업 캐스트하므로
zip(df['A'], df['B'], ...)
대신 반복해야 df[['A', 'B']].to_numpy()
합니다. 예를 들어 A가 숫자이고 B가 문자열 인 to_numpy()
경우 전체 배열을 문자열로 캐스트합니다. 원하는 문자열이 아닐 수도 있습니다. 다행히 zip
열을 함께 ping하는 것이 가장 간단한 해결 방법입니다.
* 위 의 주의 사항 섹션에 설명 된 이유로 YMMV .
명백한 예
두 팬더 열을 추가하는 간단한 예를 통해 차이점을 보여 드리겠습니다 A + B
. 이는 벡터화 가능한 연산이므로 위에서 설명한 방법의 성능을 쉽게 대조 할 수 있습니다.
참조 용 벤치마킹 코드.
그러나 항상 이것이 잘리지 않고 건조하지는 않습니다. 때로는 "작업에 가장 적합한 방법"에 대한 대답은 "데이터에 따라 다릅니다"입니다. 내 조언은 데이터에 정착하기 전에 데이터에 대한 다양한 접근 방식을 테스트하는 것입니다.
추가 자료
* Pandas 문자열 메소드는 시리즈에서 지정되었지만 각 요소에서 작동한다는 의미에서 "벡터화"됩니다. 문자열 연산은 본질적으로 벡터화하기 어렵 기 때문에 기본 메커니즘은 여전히 반복적입니다.
이 답변을 쓴 이유
내가 새로운 사용자들로부터 알게되는 일반적인 경향은 "X를 수행하기 위해 어떻게 df를 반복 할 수 있습니까?"라는 형식의 질문을하는 것입니다. iterrows()
for 루프 내에서 무언가를 수행하는 동안 호출 하는 코드를 표시합니다 . 이유는 다음과 같습니다. 벡터화 개념을 도입하지 않은 라이브러리의 새 사용자는 데이터를 반복하여 무언가를 수행 할 때 문제를 해결하는 코드를 구상 할 수 있습니다. DataFrame을 반복하는 방법을 모르는 경우 첫 번째 작업은 Google 이며이 질문에서 끝납니다. 그런 다음 수락 된 답변이 방법을 알려주는 것을보고 반복이 옳지 않은지 먼저 묻지 않고 눈을 감고이 코드를 실행합니다.
이 답변의 목표는 새로운 사용자가 반복이 모든 문제에 대한 해결책 일 필요는 없으며, 더 빠르고 더 빠르고 관용적 인 솔루션이 존재할 수 있으며이를 탐구하는 데 시간을 투자 할 가치가 있음을 이해하는 데 도움이됩니다. 반복 대 벡터화 전쟁을 시작하지는 않지만이 라이브러리의 문제에 대한 솔루션을 개발할 때 새로운 사용자에게 정보를 제공하기를 원합니다.