2016-04-01 11 views
1

Ich versuche, das zu tun, folgende:Bewerben Rückkehr Datenrahmen, wenn sie eine Serie zurückkehren sollte

  1. Wählen Sie eine zufällige Reihe von meiner Pandas Dataframe
  2. Subset der Datenrahmen nur Zeilen enthalten, die die zufällig ausgewählt entsprechen Zeile in 2 spezifischen Spalten, 'Type' und 'LocationID'.

Hier ist der entsprechende Code-Schnipsel:

import pandas as pd 

train = pd.DataFrame(
    {'Type': ['Rad', 'Rad', 'Rad', 'Rad', 'Rad'], 
    'LocationID': ['6', '6', '6', '6', '6'], 
    'UserID': [0, 1, 2, 3, 4]}) 
u1 = train.sample(n=1) 
group_feat = ['Type', 'LocationID'] 
for gf in group_feat: 
    match = train[gf].apply(lambda x: x == u1[gf]) 
    train = train.loc[match] 

Mein Code einen Fehler in der letzten Zeile von der .loc Funktion wirft:

ValueError: Cannot index with multidimensional key

Weitere Untersuchungen ergaben, dass die Art der Variable match ist keine Serie, sondern ein DataFrame mit 1 Spalte. Ich kann nicht damit rechnen, dass die Anwendungsfunktion in diesem Fall nicht einfach eine Serie zurückgeben würde. Wie kann ich das umgehen? Ich kann nicht das übliche tolist() verwenden, da diese Methode für einen DataFrame nicht verfügbar ist. Irgendeine Einsicht in die allgemeine Intuition der Pandas, die mich auf diesen Fehler aufmerksam gemacht haben? Ich habe erfolgreich apply oft vorher verwendet und in der Vergangenheit gab es den erwarteten Typ zurück.

Edit:train.info() (irrelevant Spalten entfernt Kürze halber/privacy):

<class 'pandas.core.frame.DataFrame'> 
Int64Index: 92529 entries, 0 to 92528 
Data columns (total 93 columns): 
Type            92529 non-null object 
LocationID          92529 non-null object 
UserID           92529 non-null int64 
dtypes: float64(6), int64(55), object(32) 
memory usage: 66.4+ MB 
None 
+0

Bitte senden Sie 'train.head(). Todict ('list')' und 'train.info()' so können wir (hoffentlich) das Problem reproduzieren. – unutbu

+0

@unutbu Ersteres verursachte einen'AttributeError: 'DataFrame'-Objekt hat kein Attribut' Todd'', aber ich habe die Frage bearbeitet, um die Letzteren einzuschließen. Vielen Dank. – src

+0

Entschuldigung - das hätte 'train.head(). To_dict ('list')' (mit einem Unterstrich) lesen sollen. – unutbu

Antwort

1

pandas.Series.apply(func) wird wieder ein Series wenn func eine skalare zurückgibt, oder will return a DataFrame if func returns a Series.

u1[gf] ist eine Serie so lambda x: x == u1[gf] gibt eine boolesche Serie zurück, und so endet match als ein DataFrame.

Bei der Verwendung von df.loc[key] kann key ein Slice, eine boolesche Sequenz oder ein listenartiger Indexer sein, aber kein DataFrame. Wenn key ein DataFrame ist, wird eine ValueError('Cannot index with multidimensional key') ausgelöst.


das Problem zu beheben, Sie

match = train[gf].apply(lambda x: x == u1[gf].item()) 

Da u1[gf].item() ein Skalar ist und so lambda x: x == u1[gf].item() gibt einen booleschen Skalar verwenden könnte (und match endet so, um eine Serie zu sein.)

Or Für eine bessere Leistung wäre ein besserer Weg dies zu schreiben

for gf in group_feat: 
    train = train.loc[train[gf] == u1[gf].item()] 

die Verwendung von apply mit einer Lambda-Funktion insgesamt vermeiden.

Und um Speicherplatz zu sparen (und die Leistung zu verbessern), vermeiden Sie die Zwischendatenrahmen bilden (n) durch

ersetzt
group_feat = ['Type', 'LocationID'] 
for gf in group_feat: 
    match = train[gf].apply(lambda x: x == u1[gf]) 
    train = train.loc[match] 

mit

mask = (train['Type'] = u1['Type'].item()) 
     and (train['LocationID'] = u1['LocationID'].item()) 
train = train.loc[mask] 

oder allgemeiner

group_feat = ['Type', 'LocationID'] 
mask = np.logical_and.reduce([train[col] == u1[col].item() for col in group_feat]) 
train = train.loc[mask] 

Letzteres ist besonders nützlich, wenn group_feat lang ist.


Zum Beispiel

import numpy as np 
import pandas as pd 

train = pd.DataFrame(
    {'Type': ['Rad', 'Rad', 'Rad', 'Rad', 'Rad'], 
    'LocationID': ['6', '6', '6', '6', '6'], 
    'UserID': [0, 1, 2, 3, 4]}) 
u1 = train.sample(n=1) 
group_feat = ['Type', 'LocationID'] 
mask = np.logical_and.reduce([train[col] == u1[col].item() for col in group_feat]) 
train = train.loc[mask] 
+0

Vielen Dank. Ich denke, die 'item()' Funktion ist die Sache, nach der ich suchte, aber nicht wusste, wie man danach sucht. Ich gebe das eine Chance. – src

+0

Entschuldigung, ich habe so lange gebraucht, um zu antworten, aber das funktioniert perfekt für mich, danke nochmal! – src

Verwandte Themen