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であることを知っています。私はただ一つの列を追加することについて尋ねるだけです。

を追加するには、1つの列の項目を連続したメモリに置かなければならないという明白な理由から、データのコピーが必要な場合があります。

+0

'numpy'配列(ほとんどのPandasの基礎となる構造体)では、' concatenate'はより大きな新しい配列を作成し、すべての値を(相対サイズにかかわらず)コピーします。パンダの問題で言及されているコピーは、1つの列を追加するか、または複数の列を追加する場合に適用されます。繰り返し実行するとコストが高くなります。 – hpaulj

+0

@hpaulj DFに行を追加するのを避けるために、なぜドキュメンテーションと(パンダに関するさまざまな記事の両方で)アドバイスされていますが、列の追加については言及していませんか? – max

+0

データフレームが2次元配列の場合、列を追加するのと同じように行を追加するだけです。列が構造化配列の 'fields 'である場合はDitoしかし、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

関連する問題