2017-02-24 4 views
2

Ich habe eine DataFrame, die ich mit Spalten erweitern möchte, die Daten aus der vorherigen Zeile enthalten.Umgang mit SettingWithCopyWarning beim Zuweisen von Spalten in Pandas

Dieses Skript hat den Zweck erfüllt:

#!/usr/bin/env python3 

import numpy as np 
import pandas as pd 

n = 2 

df = pd.DataFrame({'A': [1,2,3,4,5], 'B': [0,1,1,0,0]}, columns=['A', 'B']) 

df2 = df[df['B'] == 0] 
print(df2) 

for i in range(1, n+1): 
    df2['A_%d' % i] = df2['A'].shift(i) 

print(df2) 

Es gibt:

A B 
0 1 0 
3 4 0 
4 5 0 

    A B A_1 A_2 
0 1 0 NaN NaN 
3 4 0 1.0 NaN 
4 5 0 4.0 1.0 

das ist genau das, was ich will. Die DataFrame hat jetzt zwei zusätzliche Spalten A_1 und A_2, die den Wert der Spalte A und Zeilen vor enthalten.

Allerdings bekomme ich auch die Warnung:

./my_script.py:14: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame. 
Try using .loc[row_indexer,col_indexer] = value instead 

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy 
    df2['A_%d' % i] = df2['A'].shift(i) 

Das Problem kommt auf jeden Fall aus der Filterung vor, wo ich df2 erstellen. Wenn ich direkt an df arbeite, tritt das Problem nicht auf. In meiner Anwendung muss ich an mehreren Teilen meines originalen DataFrame separat arbeiten und daher die Filterung und ist definitiv erforderlich. Alle verschiedenen Teile (wie df2 hier) werden später verkettet. Ich habe ähnliche Probleme in How to deal with SettingWithCopyWarning in Pandas? und Pandas SettingWithCopyWarning gefunden, aber die Lösungen von dort beheben das Problem nicht.

Schreiben z.B.

df2[:, 'A_%d' % i] = df2['A'].shift(i) 

die gleiche Warnung immer noch auftritt.

ich mit Python arbeite 3.5.2 und Pandas 0.19.2

Antwort

3

Ich glaube, Sie brauchen copy:

df2 = df[df['B'] == 0].copy() 

Wenn Sie Werte ändern in df2 später werden Sie feststellen, dass die Änderungen nicht fortpflanzen zurück zu den ursprünglichen Daten (df), und dass Pandas warnt.

+1

Es funktioniert. Können Sie erklären, warum in diesem Fall 'copy()' aufgerufen werden muss? Zumal der Code ohne ihn (abgesehen von der Warnung) gut zu funktionieren scheint. –

+0

Erklärungen sind schwer für mich. Vielleicht besser erklären [this] (http://stackoverflow.com/a/38810015/2901002) – jezrael

+0

Ok, danke, ich denke, ich verstehe jetzt. –

Verwandte Themen