2017-03-13 6 views
1
내가 아래로, iterrows와 행하여 일을 dataframe에서 값을 계산하려는

: 업데이트 dataframe

df = pd.DataFrame([ list(range(0, 6)) + [np.NaN] * 5, 
        list(range(10,16)) + [np.NaN] * 5, 
        list(range(20,26)) + [np.NaN] * 5, 
        list(range(30,36)) + [np.NaN] * 5]) 

for (index, row) in df.iterrows(): 
    df.loc[ index, 6: 11] = row[ 1: 6] - row [ 0] 

가 왜 DF가

업데이트되지 않는 이유는 무엇입니까?

심지어 row[ 1: 6] - row [ 0]df.loc[ index, 1: 6] - df.loc[ index, 0]으로 대체하려고 시도했지만 작동하지 않습니다. 그것은 사소한 실수입니까, 아니면 마스터하지 않는 더 세밀한 개념입니까? 그리고 거기에 뭔가 더 performant입니까?

+0

귀하는 문제를 해결 한 답을 수락하고 (체크 표시를 클릭하십시오) 이것은 미래 방문자가 당신을 위해 무엇이 효과적 이었는지, 그리고 당신을 위해 무엇이 효과가 있을지를 명확하게 알 수있게합니다. 사물을 요약하는 또 다른 응답을 추가하지 마십시오. –

+0

@ Paul H : 두 답변 모두 upvote 않았다. 내 표결이 기록되었다는 메시지가 나왔습니다. 비록 내가 충분히 명성이 없기 때문에 (15 세 이하) 그들은 나타나지 않는다! – alEx

답변

3

loc을 사용한 팬더 할당은 할당 전에 색인 정렬을 수행합니다. 여기에서 열 이름이 잘못 정렬됩니다. 이 작업을 수행합니다 :

for (index, row) in df.iterrows(): 
    df.loc[ index, 6: 11] = (row[ 1: 6] - row [ 0]).values 

df 
Out[23]: 
    0 1 2 3 4 5 6 7 8 9 10 
0 0 1 2 3 4 5 1.0 2.0 3.0 4.0 5.0 
1 10 11 12 13 14 15 1.0 2.0 3.0 4.0 5.0 
2 20 21 22 23 24 25 1.0 2.0 3.0 4.0 5.0 
3 30 31 32 33 34 35 1.0 2.0 3.0 4.0 5.0 

문서 here 더 많은 정보 : .loc, .iloc 및 .ix에서 시리즈 및 DataFrame를 설정할 때

경고 팬더는 모든 축을 정렬합니다. 열이 값 지정 이전이므로 df가 수정되지 않습니다.

+0

이 답변과 문서는 나에게 의미가 없다. "정렬하는 것"은 무엇을 의미 하는가? loc은 일을 정렬하지만 왜 []는 't? – frabcus

+0

loc은 유사한 색인 된 df와 시리즈 사이에 할당을 할 때 이것이 예상 한 시간의 대부분을 차지하기 때문에 일을 정렬합니다. OP의 범인은 도메인 관련 색인이 더 이상 정의되지 않았으며 색인 액세스는 df에 대한 일종의 블라인드 윈도우 필터 (blinding windowing filter)로 수행됩니다. 이것은 특별한 경우입니다. 두 개의 적절한 인덱스를 사용하면 필터링 된 데이터를 직접 할당하고 정렬 마법을 환영합니다. – Boud

1

데이터 프레임을 반복 할 필요가 거의 없습니다. 난 그냥 이런 짓을 했을까 :

import pandas 
import numpy 
x = numpy.array([ 
    list(range(0, 6)) + [numpy.NaN] * 5, 
    list(range(10, 16)) + [numpy.NaN] * 5, 
    list(range(20, 26)) + [numpy.NaN] * 5, 
    list(range(30, 36)) + [numpy.NaN] * 5 
]) 

x[:, 6:] = x[:, 1:6] - x[:, [0]] 

pandas.DataFrame(x) 

나 제공합니다 :

 0  1  2  3  4  5 6 7 8 9 10 
0 0.0 1.0 2.0 3.0 4.0 5.0 1.0 2.0 3.0 4.0 5.0 
1 10.0 11.0 12.0 13.0 14.0 15.0 1.0 2.0 3.0 4.0 5.0 
2 20.0 21.0 22.0 23.0 24.0 25.0 1.0 2.0 3.0 4.0 5.0 
3 30.0 31.0 32.0 33.0 34.0 35.0 1.0 2.0 3.0 4.0 5.0 
0

들으을. 나는 두 가지 솔루션을 추가 :

df = pd.DataFrame([ list(range(0, 6)) + [np.NaN] * 5, 
        list(range(10,16)) + [np.NaN] * 5, 
        list(range(20,26)) + [np.NaN] * 5, 
        list(range(30,36)) + [np.NaN] * 5]) 

df.loc[ :, 6: 11] = (row[ 1: 6] - row [ 0]).values 
df 

Out[10]: 
    0 1 2 3 4 5 6 7 8 9 10 
0 0 1 2 3 4 5 1.0 2.0 3.0 4.0 5.0 
1 10 11 12 13 14 15 1.0 2.0 3.0 4.0 5.0 
2 20 21 22 23 24 25 1.0 2.0 3.0 4.0 5.0 
3 30 31 32 33 34 35 1.0 2.0 3.0 4.0 5.0 

편집 :이 작동하지 않는 사실

! 내 실제 예에서는 문제가 있으며 데이터가이 작은 예를보고 있어야하는 것이 아닙니다.

iterrows() 솔루션이 느립니다 (내 데이터 프레임은 약 9000 * 500). 따라서 numpy 배열 솔루션에 대해 설명 할 것입니다. 데이터 프레임을 numpy 배열로 변환하여 계산을 수행하고 데이터 프레임으로 돌아갑니다.

import numpy as np 
import pandas as pd 

df = pd.DataFrame([ list(range(0, 6)) + [np.NaN] * 5, 
        list(range(10,16)) + [np.NaN] * 5, 
        list(range(20,26)) + [np.NaN] * 5, 
        list(range(30,36)) + [np.NaN] * 5]) 
x = df.as_matrix() 
x[ :, 6:] = x[ :, 1: 6] - x[ :, [ 0]] 
df = pd.DataFrame(x, columns=df.columns, index=df.index, dtype='int8') 
df 

Out[15]: 
    0 1 2 3 4 5 6 7 8 9 10 
0 0 1 2 3 4 5 1 2 3 4 5 
1 10 11 12 13 14 15 1 2 3 4 5 
2 20 21 22 23 24 25 1 2 3 4 5 
3 30 31 32 33 34 35 1 2 3 4 5 
In [ ]: