2016-06-20 5 views
2

제 질문은 성능에만 관한 내용이지 의미에 관한 내용은 아닙니다.DataFrame에 열을 추가하는 과정에서 데이터가 복사됩니까?

df에 새 열을 추가하면 기존 DataFrame의 데이터가 새로운 메모리 위치로 물리적으로 복사됩니다 (예 : DataFrame이 인접 메모리를 차지하도록)?

# using pandas 0.18.1, python 3.5 
import pandas as pd 
df = pd.DataFrame({'a': range(100)}) 
b = pd.Series(range(100)) 
df['b'] = b # is this operation expensive? 
# equivalently df.loc[:, 'b'] = b 

나는 df['b'] = b는 의미 분명히 기본 데이터의 복사를 요구 b의 사본을 만들 것이다 (실험에서, 문서에서 찾을 수 없었다) 알고있다. 그러나 다른 열의 데이터가 원래 위치에 머물러 있는지 또는 때때로 이동해야하는지 잘 모릅니다.

편집 :

나는 열이 많은 수를 추가하는 expensive 것을 알고있다. 하나의 열을 추가하는 것에 대해서만 묻고 있습니다.

또한 을 추가하려면 단일 열의 항목이 인접한 메모리에 있어야한다는 분명한 이유 때문에 일부 경우에 데이터를 복사해야합니다 (또는 항상 확실하지는 않습니다).

+0

'numpy' 배열 (대부분의 팬더에 대한 기본 구조)로'concatenate'는 더 큰 새로운 배열을 만들고 모든 값을 (상대 크기에 관계없이) 복사하는 것입니다. 팬더 문제에서 언급 한 복사 작업은 하나의 열 추가 또는 여러 열 추가에 적용됩니다. 반복적으로 수행하는 경우 비용이 훨씬 많이 듭니다. – hpaulj

+0

@hpaulj 그렇다면 왜 DF에 행을 추가하는 것을 피하기 위해 문서 및 다양한 판다에 글을 올렸지 만 열 추가에 대한 언급은 없었습니까? – max

+0

데이터 프레임이 2 차원 배열 인 경우 열 추가는 행 추가만큼 비용이 많이 듭니다. Dito는 열이 구조화 된 배열의'fields '인 경우에 사용됩니다. 그러나 DF는 1 차원 배열 (열)의 목록이며 열을 추가하는 것이 더 쉬울 것입니다. – hpaulj

답변

1

나는 loc이 slowier는 나의 실험에서 생각하고 다른 인덱스 slowiest 새로운 Series 정렬 :

그러나 다른 컬럼의 데이터가 어디에 유지, 또는 필요 수 있을지 몰라 때로는 움직일 수 있습니다.

데이터가 이동되지 않고 새로운 열이 끝에 추가됩니다 (어쩌면 예외가있을 수 있지만 그것에 대해 알 수는 없습니다).

# using pandas 0.18.1, python 3.5 
import pandas as pd 
#len(df) = 10m 
df = pd.DataFrame({'a': range(10000000)}) 
b = pd.Series(range(10000000)) 
c = pd.Series(range(10000000), index=df.index) 
df['b'] = b 
df.loc[:, 'c'] = b 
df['d'] = c 
df.loc[:, 'e'] = c 
print (df) 

In [36]: %timeit df['b'] = b 
10 loops, best of 3: 23.5 ms per loop 

In [37]: %timeit df.loc[:, 'c'] = b 
The slowest run took 5.76 times longer than the fastest. This could mean that an intermediate result is being cached. 
1 loop, best of 3: 40 ms per loop 

In [38]: %timeit df['d'] = c 
10 loops, best of 3: 22.3 ms per loop 

In [39]: %timeit df.loc[:, 'e'] = c 
10 loops, best of 3: 39.5 ms per loop 

그러나 index 변경하는 경우 : 새 행을 추가하는 경우

# using pandas 0.18.1, python 3.5 
import pandas as pd 
df = pd.DataFrame({'a': range(10000000)}) 
df.index = df.index + 15 
b = pd.Series(range(10000000)) 
c = pd.Series(range(10000000), index=df.index) 
df['b'] = b 
df.loc[:, 'c'] = b 
df['d'] = c 
df.loc[:, 'e'] = c 
print (df) 

In [41]: %timeit df['b'] = b 
1 loop, best of 3: 656 ms per loop 

In [42]: %timeit df.loc[:, 'c'] = b 
1 loop, best of 3: 735 ms per loop 

In [43]: %timeit df['d'] = c 
10 loops, best of 3: 22.4 ms per loop 

In [44]: %timeit df.loc[:, 'e'] = c 
10 loops, best of 3: 56.6 ms per loop 

, 그것은 빠르고, 내 생각은 Series의 길이 따라 달라

In [68]: %timeit df.loc[10000015, :] = pd.Series([1,2,3,2,4], index=df.columns) 
1000 loops, best of 3: 274 µs per loop 

그러나 경우에하는 것은 많은 행을 추가, 그것은 비싸고 이것이 피할 수 있다고 생각합니다.

+0

그럴듯하지만, DataFrame을 구현하는 데 사용되는 내부 데이터 구조에 대한 공식 설명이 없습니까? – max

+0

예, 그렇게 생각합니다. 공식 문서에서 나는 아무것도 찾을 수 없습니다. – jezrael

+0

하지만 아마도 '팬더'전문가가 당신의 질문을 더 잘 설명 할 수 있습니다. 또 다른 옵션은 [github] (https://github.com/pydata/pandas/issues)에 새로운 질문을 작성하는 것이고'Jeff'는 더 잘 설명 할 수 있습니다. – jezrael

관련 문제