2016-11-15 1 views
1

Ich habe ein Wörterbuch mit jeder Spalte als Schlüssel in einem dataframe wie:Dynamische Vergleich mit Pandas und

dict = {"colA":1,"colB":1,"colC":1} 

mit colA, colB, COLC die Säulen meines dataframe.

Ich möchte wie etwas tun:

df.loc[(df["colA"] < = dict["colA"]) & (df["colB"] < = dict["colB"]) & (df["colC"] < = dict["colC"])] 

aber dynamisch (ich weiß nicht, die Länge der dict/Anzahl der Spalten)

Gibt es eine Möglichkeit, eine & mit dem zu tun dynamische Anzahl der Argumente?

Antwort

1

können Sie verwenden:

from functools import reduce 

df = pd.DataFrame({'colA':[1,2,0], 
        'colB':[0,5,6], 
        'colC':[1,8,9]}) 

print (df) 
    colA colB colC 
0  1  0  1 
1  2  5  8 
2  0  6  9 

d = {"colA":1,"colB":1,"colC":1} 

a = df[(df["colA"] <= d["colA"]) & (df["colB"] <= d["colB"]) & (df["colC"] <= d["colC"])] 
print (a) 
    colA colB colC 
0  1  0  1 

Lösung mit Series zu schaffen, vergleichen mit le, überprüfen Sie alle True von all und letzten Einsatz boolean indexing:

d = {"colA":1,"colB":1,"colC":1} 

s = pd.Series(d) 
print (s) 
colA 1 
colB 1 
colC 1 
dtype: int64 

print (df.le(s).all(axis=1)) 
0  True 
1 False 
2 False 
dtype: bool 

print (df[df.le(s).all(axis=1)]) 
    colA colB colC 
0  1  0  1 

Eine andere Lösung mit numpy.logical_and und reduce für Maske zu schaffen und list comprehension für die Anwendungsbedingungen:

Hier
print ([df[x] <= d[x] for x in df.columns]) 
[0  True 
1 False 
2  True 
Name: colA, dtype: bool, 0  True 
1 False 
2 False 
Name: colB, dtype: bool, 0  True 
1 False 
2 False 
Name: colC, dtype: bool] 

mask = reduce(np.logical_and, [df[x] <= d[x] for x in df.columns]) 
print (mask) 
0  True 
1 False 
2 False 
Name: colA, dtype: bool 

print (df[mask]) 
    colA colB colC 
0  1  0  1 
1

ist eine SQL-ähnliche Lösung, die verwendet .query() Methode:

Daten:

In [23]: df 
Out[23]: 
    colA colB colC 
0  2  2  5 
1  3  0  8 
2  5  9  2 
3  3  0  2 
4  9  1  3 
5  7  5  6 
6  7  8  0 
7  0  4  1 
8  8  2  6 
9  9  6  7 

Lösung:

In [20]: dct = {"colA":4,"colB":4,"colC":4} 

In [21]: qry = ' and '.join(('{0[0]} <= {0[1]}'.format(tup) for tup in dct.items())) 

In [22]: qry 
Out[22]: 'colB <= 4 and colA <= 4 and colC <= 4' 

In [24]: df.query(qry) 
Out[24]: 
    colA colB colC 
3  3  0  2 
7  0  4  1 
Verwandte Themen