2012-08-30 12 views
62

Ich versuche, eine ziemlich große CSV-Datei mit Pandas zu lesen und es in zwei zufällige Stücke aufzuteilen, von denen eine 10% der Daten und die andere 90% ist.Pandas: Sampling eines DataFrame

Hier ist meine aktuelle Versuch:

rows = data.index 
row_count = len(rows) 
random.shuffle(list(rows)) 

data.reindex(rows) 

training_data = data[row_count // 10:] 
testing_data = data[:row_count // 10] 

Aus irgendeinem Grund sklearn wirft diesen Fehler, wenn ich versuche, innerhalb eines SVM-Klassifikator eine dieser resultierenden Datenrahmen Objekte zu verwenden:

IndexError: each subindex must be either a slice, an integer, Ellipsis, or newaxis 

Ich denke, Ich mache es falsch. Gibt es einen besseren Weg, dies zu tun?

+3

übrigens das richtig sowieso nicht zufällig mischen würde - das Problem ist, 'random.shuffle (Liste (Zeilen))' . 'shuffle' ändert die Daten, auf denen es arbeitet, aber wenn Sie' list (rows) 'aufrufen, erstellen Sie eine Kopie von' rows', die verändert und dann weggeworfen werden - die zugrunde liegende Pandas-Serie, 'rows', ist unverändert. Eine Lösung besteht darin, danach 'rows = list (rows)', dann 'random.shuffle (rows)' und 'data.reindex (rows)' aufzurufen. –

Antwort

76

Welche Version von Pandas verwendest du? Für mich funktioniert dein Code gut (ich bin auf Git Master).

konnte Ein anderer Ansatz sein:

In [117]: import pandas 

In [118]: import random 

In [119]: df = pandas.DataFrame(np.random.randn(100, 4), columns=list('ABCD')) 

In [120]: rows = random.sample(df.index, 10) 

In [121]: df_10 = df.ix[rows] 

In [122]: df_90 = df.drop(rows) 

Neuere Version (ab 0.16.1 auf) direkt unterstützt dies: http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.sample.html

+7

Ein anderer Ansatz ist die Verwendung von 'np.random.permuation' –

+1

@WesMcKinney: Ich stelle fest, dass 'np.random.permutation' die Spaltennamen aus dem Datenrahmen entfernt, weil' np.random.permutation'. Gibt es eine Methode in Pandas, die den Datenrahmen unter Beibehaltung der Spaltennamen mischen würde? – hlin117

+4

@hlin df.loc [np.random.permutation (df.index)] mischt den Datenrahmen und behält die Spaltennamen bei. –

77

ich gefunden habe, dass np.random.choice() neu in NumPy 1.7.0 funktioniert recht gut für Dies.

Zum Beispiel können Sie die Indexwerte von einem DataFrame übergeben und und die ganze Zahl 10, um 10 zufällige gleichmäßig abgetastete Zeilen auszuwählen.

rows = np.random.choice(df.index.values, 10) 
sampled_df = df.ix[rows] 
+0

mit ipython timeit es dauert die Hälfte von 'random.sample' Zeit .. genial – gc5

+0

+1 für die Verwendung von np.random.choice. Auch wenn Sie eine 'pd.Series' von Wahrscheinlichkeiten,' prob' haben, können Sie aus dem Index wie folgt auswählen: 'np.random.choice (prob.index.values, p = prob.values)' – LondonRob

+37

Don ' Vergessen Sie nicht, replace = False anzugeben, wenn Sie die Stichprobe ohne Ersatz nehmen möchten.Andernfalls kann diese Methode möglicherweise mehrmals dieselbe Zeile abtasten. –

13

Pandas 0.16.1 haben eine sample Methode dafür.

+0

Schön! Aber Sie müssen immer noch alle Daten im Speicher laden, oder? – Nikolay

+0

Ich mache es nach dem Laden der Daten im Speicher. – hurrial

17

Neu in der Version 0.16.1:

sample_dataframe = your_dataframe.sample(n=how_many_rows_you_want) 

doc hier: http://pandas.pydata.org/pandas-docs/version/0.17.0/generated/pandas.DataFrame.sample.html

+0

Sobald Sie Ihren sample_dataframe haben, wie subtrahieren Sie ihn von your_dataframe? –

+0

@ChrisNielsen Fragen Sie so, dass Sie eine Kreuzvalidierung durchführen können? Wenn dem so ist, empfehle ich http://scikit-learn.org/stable/modules/cross_validation.html, da es dir alle deine Trainings- und Testdatensätze (X_train, X_test, y_train, y_test) direkt gibt – dval