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)]

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)]

158

Betrachten Sie auch Serien zwischen :

df = df[df['closing_price'].between(99, 101)]

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

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


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')

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)]

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

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.