팬더의 데이터 프레임에서 행을 반복하는 방법


질문

 

팬더에서 데이터 프레임이 있습니다.

import pandas as pd
inp = [{'c1':10, 'c2':100}, {'c1':11,'c2':110}, {'c1':12,'c2':120}]
df = pd.DataFrame(inp)
print df

산출:

   c1   c2
0  10  100
1  11  110
2  12  120

이제는이 프레임의 행을 반복하고 싶습니다.모든 행에 대해 열의 이름으로 요소 (셀의 값)에 액세스 할 수 있습니다.예를 들어:

for row in df.rows:
   print row['c1'], row['c2']

팬더에서 그 일을 할 수 있습니까?

나는이 유사한 질문을 발견했다.하지만 필요한 대답을주지 않습니다.예를 들어, 사용하기 위해 제안 사항이 있습니다.

for date, row in df.T.iteritems():

또는

for row in df.iterrows():

그러나 나는 행 객체가 무엇인지 이해하지 못합니다.


답변

 

DataFrame.IterRows는 인덱스와 행 (시리즈로)을 모두 생성하는 생성기입니다.

import pandas as pd

df = pd.DataFrame({'c1': [10, 11, 12], 'c2': [100, 110, 120]})
df = df.reset_index()  # make sure indexes pair with number of rows
for index, row in df.iterrows():
    print(row['c1'], row['c2'])
10 100
11 110
12 120


답변

팬더의 데이터 프레임에서 행을 반복하는 방법은 무엇입니까?

답변 :하지 마십시오!

팬더의 반복은 반 패턴이며 다른 모든 옵션을 소모했을 때만해야 할 일입니다."iter"가 수천 줄 이상 동안 "iter"로 함수를 사용해서는 안됩니다. 그렇지 않으면 많은 대기 중에 익숙해 져야합니다.

데이터 프레임을 인쇄 하시겠습니까?dataframe.to_string ()을 사용하십시오.

당신은 뭔가를 계산하고 싶습니까?이 경우이 순서로 메소드를 검색하십시오 (여기에서 수정 된 목록) :

  1. Vectorization
  2. Cython routines
  3. List Comprehensions (vanilla for loop)
  4. DataFrame.apply(): i)  Reductions that can be performed in Cython, ii) Iteration in Python space
  5. DataFrame.itertuples() and iteritems()
  6. DataFrame.iterrows()

Iterlows 및 Itertuples (이 질문에 대한 답변에서 많은 투표 수신)은 순차적 인 처리를위한 행 오브젝트 / 이름 임원을 생성하는 것과 같은 매우 드문 상황에서 사용되어야합니다. 이는 실제로 이러한 기능이 유용한 유일한 것입니다.

권위에 호소하십시오

문서 페이지는 반복적 인 빨간색 경고 상자가 있습니다.

팬더 객체를 통해 반복하는 것은 일반적으로 느린 것입니다.대부분의 경우 행을 수동으로 반복하는 것은 필요하지 않습니다 [...].

* 실제로는 "하지 않는 것"보다는 조금 더 복잡합니다.df.iterRows ()이 질문에 대한 정답은 "ops 벡터화"가 더 좋습니다.나는 반복을 피할 수없는 상황이 있다는 것을 인정할 것이다 (예를 들어, 결과가 이전 행에 대해 계산 된 값에 의존하는 일부 작업).그러나 언제 알 수있는 도서관에 익숙해 져 있습니다.반복 솔루션이 필요한지 여부를 확실하지 않으면 아마도 그렇지 않을 것입니다.추신 :이 답변을 작성하기 위해 나의 이론적 근거에 대해 더 많이 알고, 바로 아래로 건너 뜁니다.


루핑보다 빠르게 : Vectorization, Cython.

좋은 수의 기본 작동 및 계산은 팬더 (숫자를 통해 또는 Cythonized 함수를 통해)에 의해 "벡터화"됩니다.여기에는 산술, 비교, (대부분) 감소, 재구성 (선회), 조인 및 Groupby 작업이 포함됩니다.필수 기본 기능에 대한 설명서를 통해 문제가 적절한 벡터화 된 방법을 찾습니다.

존재하지 않으면 사용자 정의 용이성 확장을 사용하여 자신만의 자신을 써주십시오.


다음 가장 좋은 일 : 목록 포괄적 인 *

목록 포괄적 인 숫자가없는 경우의 다음 포트 여야합니다. 1) 사용 가능한 솔루션이 없습니다. 2) 성능이 중요하지만 코드를 강화하는 번거 로움을 겪을 정도로 중요하지는 않습니다.코드에서.많은 일반적인 팬더 작업에 대해 목록 포괄적 인 목록을 충분히 빠르게 (그리고 때로는 더 빠르게) 충분히 빠르게 (그리고 때로는 더 빠르게) 될 것을 제안 할 수있는 좋은 증거가 있습니다.

수식은 간단합니다.

# 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'])]

기능에 비즈니스 논리를 캡슐화 할 수있는 경우, 호출하는 목록 이해를 사용할 수 있습니다.원시 Python 코드의 단순성과 속도를 통해 임의로 복잡한 일이 작동 할 수 있습니다.

경고

목록 포괄적 인 데이터 유형이 쉽게 작동하기 쉽고 데이터 유형이 일관성이 있으므로 NAN이 없지만 항상 보장 할 수는 없습니다.

  1. The first one is more obvious, but when dealing with NaNs, prefer in-built pandas methods if they exist (because they have much better corner-case handling logic), or ensure your business logic includes appropriate NaN handling logic.
  2. When dealing with mixed data types you should iterate over zip(df['A'], df['B'], ...) instead of df[['A', 'B']].to_numpy() as the latter implicitly upcasts data to the most common type. As an example if A is numeric and B is string, to_numpy() will cast the entire array to string, which may not be what you want. Fortunately zipping your columns together is the most straightforward workaround to this.

* 귀하의 마일리지는 위의주의 사항에 요약 된 이유에 따라 다를 수 있습니다.


명백한 예

두 개의 팬더 컬럼 A + B를 추가하는 간단한 예와의 차이를 입증합시다. 이는 vectorizable Operaton이므로 위에 논의 된 방법의 성능을 쉽게 대조 할 수 있습니다.

Benchmarking code, for your reference. The line at the bottom measures a function written in numpandas, a style of Pandas that mixes heavily with NumPy to squeeze out maximum performance. Writing numpandas code should be avoided unless you know what you're doing. Stick to the API where you can (i.e., prefer vec over vec_numpy).

I should mention, however, that it isn't always this cut and dry. Sometimes the answer to "what is the best method for an operation" is "it depends on your data". My advice is to test out different approaches on your data before settling on one.


My Personal Opinion *

Most of the analyses performed on the various alternatives to the iter family has been through the lens of performance. However, in most situations you will typically be working on a reasonably sized dataset (nothing beyond a few thousand or 100K rows) and performance will come second to simplicity/readability of the solution.

Here is my personal preference when selecting a method to use for a problem.

For the novice:

Vectorization (when possible); apply(); List Comprehensions; itertuples()/iteritems(); iterrows(); Cython

For the more experienced:

Vectorization (when possible); apply(); List Comprehensions; Cython; itertuples()/iteritems(); iterrows()

Vectorization prevails as the most idiomatic method for any problem that can be vectorized. Always seek to vectorize! When in doubt, consult the docs, or look on Stack Overflow for an existing question on your particular task.

I do tend to go on about how bad apply is in a lot of my posts, but I do concede it is easier for a beginner to wrap their head around what it's doing. Additionally, there are quite a few use cases for apply has explained in this post of mine.

Cython ranks lower down on the list because it takes more time and effort to pull off correctly. You will usually never need to write code with pandas that demands this level of performance that even a list comprehension cannot satisfy.

* As with any personal opinion, please take with heaps of salt!


Further Reading

* Pandas string methods are "vectorized" in the sense that they are specified on the series but operate on each element. The underlying mechanisms are still iterative, because string operations are inherently hard to vectorize.


Why I Wrote this Answer

A common trend I notice from new users is to ask questions of the form "How can I iterate over my df to do X?". Showing code that calls iterrows() while doing something inside a for loop. Here is why. A new user to the library who has not been introduced to the concept of vectorization will likely envision the code that solves their problem as iterating over their data to do something. Not knowing how to iterate over a DataFrame, the first thing they do is Google it and end up here, at this question. They then see the accepted answer telling them how to, and they close their eyes and run this code without ever first questioning if iteration is the right thing to do.

The aim of this answer is to help new users understand that iteration is not necessarily the solution to every problem, and that better, faster and more idiomatic solutions could exist, and that it is worth investing time in exploring them. I'm not trying to start a war of iteration vs. vectorization, but I want new users to be informed when developing solutions to their problems with this library.



답변

먼저 데이터 프레임에서 행을 반복 해야하는 경우 고려하십시오.대안에 대한 답변을 확인하십시오.

행을 반복 해야하는 경우 아래의 방법을 사용할 수 있습니다.다른 답변에서 언급되지 않은 중요한주의 사항을 유의하십시오.

DataFrame.itErrows () 색인의 경우 df.iterrows ()의 행 : 인쇄 (행 [ "C1"], 행 [ "C2"])) dataFrame.itertupples () df.itertuples의 행 (index = true, name = 'pandas') : 인쇄 (row.c1, row.c2)

itertuples ()는 iterRown ()보다 빠르게되어야합니다 ().

그러나 문서 (Pandas 0.24.2)에 따라 알아 두십시오.

iTerRows : dtype이 행에서 행까지 일치하지 않을 수 있습니다.

IterRows는 각 행에 대해 일련의 시리즈를 반환하기 때문에 행을 통해 dtypes를 보존하지 않습니다 (Datypes는 DataFrames의 열에 보존됩니다).행을 반복하는 동안 DTYPES를 유지하려면 값의 namedSuples를 반환하는 itertuples ()를 사용하는 것이 좋습니다.

IterRows : 행을 수정하지 마십시오

당신은 당신이 반복하는 것을 결코 수정해야합니다.이것은 모든 경우에 일할 수 없습니다.데이터 유형에 따라 반복자가 복사본을 반환하고 뷰가 아니며 쓰는 것이 효과가 없습니다.

대신 dataframe.apply ()를 사용하십시오.

    new_df = df.apply(lambda x: x * 2)

Itertuples :

열 이름이 유효하지 않은 파이썬 식별자가 잘못되거나 밑줄로 반복되거나 시작되면 위치 이름으로 이름이 바뀝니다.많은 수의 열 (> 255)을 사용하면 일반 튜플이 반환됩니다.

자세한 내용은 반복적으로 팬더 문서를 참조하십시오.



답변

df.iterrows ()를 사용해야합니다.시리즈 오브젝트를 작성해야하기 때문에 ROW-BY-ROW-LOW가 특히 효율적이지는 않습니다.



답변

IterRows ()는 좋은 옵션이지만 때로는 iTertuples ()가 훨씬 빠르게 될 수 있습니다.

df = pd.DataFrame({'a': randn(1000), 'b': randn(1000),'N': randint(100, 1000, (1000)), 'x': 'x'})

%timeit [row.a * 2 for idx, row in df.iterrows()]
# => 10 loops, best of 3: 50.3 ms per loop

%timeit [row[1] * 2 for row in df.itertuples()]
# => 1000 loops, best of 3: 541 µs per loop


답변

다음과 같이 df.iloc 함수를 사용할 수 있습니다.

for i in range(0, len(df)):
    print(df.iloc[i]['c1'], df.iloc[i]['c2'])
출처:https://stackoverflow.com/questions/16476924/how-to-iterate-over-rows-in-a-dataframe-in-pandas