2016-07-04 6 views
6

Ich habe einen Pandas Datenrahmen, deren Einträge alle Saiten:Wählen Reihen bestimmte Werte von Pandas enthalten Dataframe

A  B  C 
1 apple banana pear 
2 pear pear apple 
3 banana pear pear 
4 apple apple pear 

etc. Ich möchte alle Zeilen auszuwählen, die eine bestimmte Zeichenfolge enthalten, sagen wir, ‚Banane‘. Ich weiß nicht, in welcher Spalte es jedes Mal erscheinen wird. Natürlich kann ich eine for-Schleife schreiben und über alle Zeilen iterieren. Aber gibt es einen leichteren oder schnelleren Weg, dies zu tun?

+3

Sie können auch einfach 'df [df.values ​​== 'banana']' –

Antwort

2

Mit NumPy, könnte es vektorisiert wird für so viele Strings zu suchen, wie Sie wollen, wie so -

def select_rows(df,search_strings): 
    unq,IDs = np.unique(df,return_inverse=True) 
    unqIDs = np.searchsorted(unq,search_strings) 
    return df[((IDs.reshape(df.shape) == unqIDs[:,None,None]).any(-1)).all(0)] 

Probelauf -

In [393]: df 
Out[393]: 
     A  B  C 
0 apple banana pear 
1 pear pear apple 
2 banana pear pear 
3 apple apple pear 

In [394]: select_rows(df,['apple','banana']) 
Out[394]: 
     A  B  C 
0 apple banana pear 

In [395]: select_rows(df,['apple','pear']) 
Out[395]: 
     A  B  C 
0 apple banana pear 
1 pear pear apple 
3 apple apple pear 

In [396]: select_rows(df,['apple','banana','pear']) 
Out[396]: 
     A  B  C 
0 apple banana pear 
+0

Eigentlich ist dies einfacher zu verwenden, wenn nach mehreren Zeichenfolgen gesucht wird – mcglashan

3

Sie können eine boolean Maske erstellen die gesamte df gegen die Zeichenfolge aus dem Vergleich und rufen dropna param vorbei how='all' Zeilen fallen zu lassen, wo die Zeichenfolge nicht in allen Spalten angezeigt wird:

für mehrere Werte testen Sie können mehrere Masken verwenden:

:

In [90]: 
banana = df[(df=='banana')].dropna(how='all') 
banana 

Out[90]: 
     A  B C 
1  NaN banana NaN 
3 banana  NaN NaN 

In [91]:  
apple = df[(df=='apple')].dropna(how='all') 
apple 

Out[91]: 
     A  B  C 
1 apple NaN NaN 
2 NaN NaN apple 
4 apple apple NaN 

Sie index.intersection indizieren nur die gemeinsamen Indexwerte verwenden können

In [93]: 
df.loc[apple.index.intersection(banana.index)] 

Out[93]: 
     A  B  C 
1 apple banana pear 
+0

Vielen Dank. Dies funktioniert sicherlich, wenn ich nach einer Saite suche. Was ist, wenn ich Zeilen auswählen möchte, die sowohl "Banane" als auch "Apfel" enthalten? – mcglashan

+0

Ich kenne keine Pandas, aber vielleicht so etwas: 'df [df == 'banana', 'apple']. Dropna (wie = 'alles')'? – Deadpool

+0

@ Andromedae93 Das gibt mir einen TypeError – mcglashan

3

Für einzelnen Suchwert

df[df.values == "banana"] 

oder

df[df.isin(['banana'])] 

Für mehrere Suchbegriffe:

df[(df.values == "banana")|(df.values == "apple") ] 

oder

df[df.isin(['banana', "apple"])] 

    #   A  B  C 
    # 1 apple banana NaN 
    # 2  NaN  NaN apple 
    # 3 banana  NaN NaN 
    # 4 apple apple NaN 

Von Divakar: Linien mit beiden zurückgegeben werden.

select_rows(df,['apple','banana']) 

#   A  B  C 
# 0 apple banana pear 
+0

Die letzte Zeile gibt mir tatsächlich einen leeren Datenrahmen, wenn ich es versuche – mcglashan

Verwandte Themen