Wie wähle ich in Python Pandas Zeilen in einem DataFrame zwischen zwei Werten aus?

94

Ich versuche, einen DataFrame so zu ändern, dass dfer nur Zeilen enthält, für die die Werte in der Spalte closing_pricezwischen 99 und 101 liegen, und versuche dies mit dem folgenden Code.

Ich erhalte jedoch den Fehler

ValueError: Der Wahrheitswert einer Serie ist nicht eindeutig. Verwenden Sie a.empty, a.bool (), a.item (), a.any () oder a.all ()

und ich frage mich, ob es einen Weg gibt, dies ohne Schleifen zu tun.

df = df[(99 <= df['closing_price'] <= 101)]
user131983
quelle
Das Problem hierbei ist, dass Sie einen Skalar nicht mit einem Array vergleichen können, daher der Fehler. Für Vergleiche müssen Sie die bitweisen Operatoren verwenden und sie aufgrund der Vorrangstellung des Operators in Klammern setzen
EdChum
df.queryund pd.evalscheinen gut für diesen Anwendungsfall zu passen. Informationen zur pd.eval()Funktionsfamilie, ihren Funktionen und Anwendungsfällen finden Sie unter Auswertung dynamischer Ausdrücke in Pandas mit pd.eval () .
CS95

Antworten:

100

Sie sollten ()Ihren booleschen Vektor gruppieren, um Mehrdeutigkeiten zu beseitigen.

df = df[(df['closing_price'] >= 99) & (df['closing_price'] <= 101)]
Jianxun Li
quelle
158

Betrachten Sie auch Serien zwischen :

df = df[df['closing_price'].between(99, 101)]
Parfait
quelle
5
Option inclusive=Truewird standardmäßig in verwendet between, so dass Sie wie folgt abfragen könnendf = df[df['closing_price'].between(99, 101)]
Anton Ermakov
3
Das ist die beste Antwort! gut gemacht!
PEBKAC
Gibt es "nicht zwischen" Funktionen in Pandas? Ich finde es nicht.
Dsugasa
2
@dsugasa, benutze den Tilde-Operator mit between.
Parfait
1
@dsugasa zBdf = df[~df['closing_price'].between(99, 101)]
Jan33
22

Es gibt eine schönere Alternative - verwenden Sie die query () -Methode:

In [58]: df = pd.DataFrame({'closing_price': np.random.randint(95, 105, 10)})

In [59]: df
Out[59]:
   closing_price
0            104
1             99
2             98
3             95
4            103
5            101
6            101
7             99
8             95
9             96

In [60]: df.query('99 <= closing_price <= 101')
Out[60]:
   closing_price
1             99
5            101
6            101
7             99

UPDATE: Beantwortung des Kommentars:

Ich mag die Syntax hier, bin aber beim Versuch, sie mit Ausdruck zu kombinieren, heruntergefallen. df.query('(mean + 2 *sd) <= closing_price <=(mean + 2 *sd)')

In [161]: qry = "(closing_price.mean() - 2*closing_price.std())" +\
     ...:       " <= closing_price <= " + \
     ...:       "(closing_price.mean() + 2*closing_price.std())"
     ...:

In [162]: df.query(qry)
Out[162]:
   closing_price
0             97
1            101
2             97
3             95
4            100
5             99
6            100
7            101
8             99
9             95
MaxU
quelle
Ich mag die Syntax hier, bin aber beim Versuch, sie mit Ausdruck zu kombinieren, heruntergefallen. df.query ('(Mittelwert + 2 * sd) <= Schlusspreis <= (Mittelwert + 2 * sd)')
Mapping dom
1
@mappingdom, was ist meanund sd? Sind das Spaltennamen?
MaxU
nein , sie sind die berechneten Mittelwert und Standardabweichung als Schwimmer gespeichert
Mapping dom
@mappingdom, was meinst du mit "gespeichert"?
MaxU
@mappingdom, ich habe meinen Beitrag aktualisiert - haben Sie danach gefragt?
MaxU
9

Sie können auch .between()Methode verwenden

emp = pd.read_csv("C:\\py\\programs\\pandas_2\\pandas\\employees.csv")

emp[emp["Salary"].between(60000, 61000)]

Ausgabe

Geben Sie hier die Bildbeschreibung ein

Riz.Khan
quelle
6
newdf = df.query('closing_price.mean() <= closing_price <= closing_price.std()')

oder

mean = closing_price.mean()
std = closing_price.std()

newdf = df.query('@mean <= closing_price <= @std')
CrashMOGWAI
quelle
3

Wenn Sie mit mehreren Werten und mehreren Eingaben arbeiten, können Sie auch eine solche Apply-Funktion einrichten. In diesem Fall wird ein Datenrahmen nach GPS-Standorten gefiltert, die in bestimmte Bereiche fallen.

def filter_values(lat,lon):
    if abs(lat - 33.77) < .01 and abs(lon - -118.16) < .01:
        return True
    elif abs(lat - 37.79) < .01 and abs(lon - -122.39) < .01:
        return True
    else:
        return False


df = df[df.apply(lambda x: filter_values(x['lat'],x['lon']),axis=1)]
Spatz
quelle
0

An Stelle von

df = df[(99 <= df['closing_price'] <= 101)]

Sie sollten dies verwenden

df = df[(df['closing_price']>=99 ) & (df['closing_price']<=101)]

Wir müssen die bitweisen Logikoperatoren |, &, ~, ^ von NumPy verwenden, um Abfragen zusammenzusetzen. Außerdem sind die Klammern wichtig für die Priorität des Operators.

Weitere Informationen finden Sie unter folgendem Link: Vergleiche, Masken und Boolesche Logik

Rushabh Agarwal
quelle