2017-04-21 4 views
0

Nach einer Weile Suche kann ich keine Antwort auf was ein häufiges Problem sein, so dass Zeiger begrüßen.Wählen Sie Teile von Pandas Dataframe basierend auf Werten in einer Liste in einer Spalte

Ich habe einen Datenrahmen:

df = DataFrame({'A' : [5,6,3,4], 'B' : [1,2,3,5], 'C' : [['a','b'],['b','c'] ,['g','h'],['x','y']]}) 

und ich möchte eine Teilmenge davon (einige Zeilen) auszuwählen, die Werte in den Listen in der ‚C‘ Spalte haben, die in einer Liste angezeigt Dinge, an denen ich interessiert bin

listOfInterestingThings = [a, g] 

so, wenn die Filter angewandt wird ich eine df1 hätte:

df1 = 
A B  C  
5 1 ['a','b'] 
3 3 ['g','h'] 

Der Datenrahmen Ich bin der Umgang mit ist ein massiver Import von Rohdaten in dem RAM ~ 12GB in der aktuellen df Form. Etwa die Hälfte davon auf der Festplatte als eine Reihe von JSON-Dateien.

+3

Standardwarnung: Nicht skalare Elemente (z. B. Listen) in Serien und Datenrahmen haben keine gute Unterstützung und führen wahrscheinlich zu mysteriösem und unerwartetem Verhalten. Voreingenommener Benutzer! – DSM

+0

@DSM interessant. hatte keine Ahnung. Hast du Vorschläge? Was ich tue, ist die grundlegende Manipulation eines großen Textkorpus, bevor ich einige ML ausprobiere, um über Themen zu trainieren. Die Daten ~ 6 GB von JSON-Dateien. Jedes Dokument wird durch ein json-Element mit Tags für "body" und "topics" dargestellt, die Themen werden als Liste dargestellt, z. ['topic1', 'topic2'] Ich lade Daten in ein df mit pd.DataFrame.from_dict. Haben Sie einen Vorschlag für eine bessere Möglichkeit, große Datensätze mit dieser Struktur zu manipulieren? –

Antwort

2

Ich stimme voll und ganz mit @DSM überein.

Als letztes Mittel können Sie verwenden:

In [21]: df.loc[pd.DataFrame(df.C.values.tolist(), index=df.index) \ 
        .isin(listOfInterestingThings).any(1)] 
Out[21]: 
    A B  C 
0 5 1 [a, b] 
2 3 3 [g, h] 

oder:

In [11]: listOfInterestingThings = set(['a', 'g']) 

In [12]: df.loc[df.C.apply(lambda x: len(set(x) & listOfInterestingThings) > 0)] 
Out[12]: 
    A B  C 
0 5 1 [a, b] 
2 3 3 [g, h] 

Erläuterung:

In [22]: pd.DataFrame(df.C.values.tolist(), index=df.index) 
Out[22]: 
    0 1 
0 a b 
1 b c 
2 g h 
3 x y 

In [23]: pd.DataFrame(df.C.values.tolist(), index=df.index).isin(listOfInterestingThings) 
Out[23]: 
     0  1 
0 True False 
1 False False 
2 True False 
3 False False 
1

Dies funktioniert auch:

df[list(np.any(('a' in i) | ('g' in i) for i in df.C.values))] 

    A B  C 
0 5 1 [a, b] 
2 3 3 [g, h] 

Benchmarks:

time df.loc[df.C.apply(lambda x: len(set(x) & listOfInterestingThings)> 0)] 

CPU times: user 873 µs, sys: 193 µs, total: 1.07 ms 
Wall time: 987 µs 

time df[list(np.any(('a' in i) | ('g' in i) for i in df.C.values))] 

CPU times: user 1.02 ms, sys: 224 µs, total: 1.24 ms 
Wall time: 1.08 ms 

time df.loc[pd.DataFrame(df.C.values.tolist(), index=df.index).isin(listOfInterestingThings).any(1)] 

CPU times: user 2.58 ms, sys: 1.01 ms, total: 3.59 ms 
Wall time: 5.41 ms 

kurz So, @ MAXU Antwort die schnellste Methode ist.

Verwandte Themen