1

SettingWithCopy悪名高い警告について多くの質問を見てきました。私はそれらのいくつかにあえて答えることさえしました。最近、このトピックに関する回答をまとめていて、データフレーム ビューの利点を提示したいと考えていました。なぜデータフレームビューを作成するのが良い考えなのか、またはそれが生成するものは何であれ、具体的なデモンストレーションを作成できませんでしたSettingWithCopy

検討df

df = pd.DataFrame([[1, 2], [3, 4]], list('ab'), list('AB'))
df

   A  B
x  1  2
y  3  4

そして、dfvこれはのコピーですdf

dfv = df[['A']]

print(dfv.is_copy)

<weakref at 0000000010916E08; to 'DataFrame' at 000000000EBF95C0>

print(bool(dfv.is_copy))

True

私は生成することができますSettingWithCopy

dfv.iloc[0, 0] = 0

ここに画像の説明を入力


ただし、dfv変わった

print(dfv)

   A
a  0
b  3

dfしていない

print(df)

   A  B
x  1  2
y  3  4

そしてdfvまだコピーです

print(bool(dfv.is_copy))

True

私が変わればdf

df.iloc[0, 0] = 7
print(df)

   A  B
x  7  2
y  3  4

しかしdfv、変わっていません。しかし、私はdfから参照することができますdfv

print(dfv.is_copy())

   A  B
x  7  2
y  3  4

質問

dfv独自のデータを保持し (つまり、実際にはメモリを節約しない)、警告にもかかわらず代入操作を介して値を代入する場合、なぜ最初から参照を保存して生成SettingWithCopyWarningする必要があるのでしょうか?

具体的なメリットは何ですか?

4

1 に答える 1

3

これについては、多くの既存の議論があります。たとえば、試行された PR を含めて、こちらを参照してください。ビューの真のコピー オン ライトが「pandas 2.0」リファクタリングの一部と見なされていることも注目に値します。こちらを参照してください。

あなたの例で参照が維持されている理由は、特にそれがビューではないためです。誰かがこれを試みると、警告が表示されます。

df[['A']].iloc[0, 0] = 1

編集:

「ビューを使用する理由」に関しては、パフォーマンス/メモリ上の理由です。基本的なインデックス作成 (列の選択) を考えてみましょう。この操作はビューを取得するため、ほぼ瞬時に実行されます。

df = pd.DataFrame(np.random.randn(1000000, 2), columns=['a','b'])

%timeit df['a']
100000 loops, best of 3: 2.13 µs per loop

一方、コピーを取ることには、取るに足らないコストがかかります。

%timeit df['a'].copy()
100 loops, best of 3: 4.28 ms per loop

このパフォーマンス コストは、たとえば 2 つの操作を足しSeries合わせるなど、多くの操作で発生します。

%timeit df['a'] + df['b']
100 loops, best of 3: 4.31 ms per loop

%timeit df['a'].copy() + df['b'].copy()
100 loops, best of 3: 13.3 ms per loop
于 2016-09-12T17:54:17.207 に答える