Bagaimana cara memilih baris dalam DataFrame antara dua nilai, dengan Python Pandas?


102

Saya mencoba mengubah DataFrame dfagar hanya berisi baris yang nilai dalam kolomnya closing_priceantara 99 dan 101 dan mencoba melakukan ini dengan kode di bawah ini.

Namun, saya mendapatkan kesalahannya

ValueError: Nilai kebenaran dari suatu Seri tidak jelas. Gunakan a.empty, a.bool (), a.item (), a.any () atau a.all ()

dan saya ingin tahu apakah ada cara untuk melakukan ini tanpa menggunakan loop.

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

Masalahnya di sini adalah bahwa Anda tidak dapat membandingkan skalar dengan array, maka kesalahannya, untuk perbandingan Anda harus menggunakan operator bitwise dan menyertakannya dalam tanda kurung karena prioritas operator
EdChum

df.querydan pd.evalsepertinya cocok untuk kasus penggunaan ini. Untuk informasi tentang pd.eval()keluarga fungsi, fitur dan kasus penggunaannya, silakan kunjungi Evaluasi Ekspresi Dinamis di pandas menggunakan pd.eval () .
cs95

Jawaban:


108

Anda harus menggunakan ()untuk mengelompokkan vektor boolean Anda untuk menghilangkan ambiguitas.

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

177

Perhatikan juga rangkaian antara :

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

6
Opsi inclusive=Truedigunakan secara default di between, sehingga Anda dapat melakukan kueri seperti inidf = df[df['closing_price'].between(99, 101)]
Anton Ermakov

3
ini jawaban terbaik! kerja bagus!
PEBKAC

Apakah ada fungsi "tidak di antara" di panda? Saya tidak menemukannya.
dsugasa

3
@dsugasa, gunakan operator tilde dengan between.
Parfait

1
@dsugasa misalnyadf = df[~df['closing_price'].between(99, 101)]
Jan33

23

ada alternatif yang lebih bagus - gunakan metode query () :

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: menjawab komentar:

Saya suka sintaks di sini tetapi gagal saat mencoba menggabungkan dengan ekspresi; 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

Saya suka sintaks di sini tetapi gagal saat mencoba menggabungkan dengan ekspresi; df.query ('(mean + 2 * sd) <= closing_price <= (mean + 2 * sd)')
memetakan dom

1
@mappingdom, apa itu meandan sd? Apakah itu nama kolom?
MaxU

tidak, mereka adalah rata-rata yang dihitung dan deviasi standar yang disimpan sebagai float
mapping dom

@mappingdom, apa maksudmu mengatakan "disimpan"?
MaxU

@mappingdom, saya telah memperbarui posting saya - apakah itu yang Anda minta?
MaxU

9

Anda juga bisa menggunakan .between()metode

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

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

Keluaran

masukkan deskripsi gambar di sini


7
newdf = df.query('closing_price.mean() <= closing_price <= closing_price.std()')

atau

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

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

3

Jika Anda berurusan dengan banyak nilai dan beberapa masukan, Anda juga dapat mengatur fungsi terapan seperti ini. Dalam hal ini memfilter kerangka data untuk lokasi GPS yang termasuk dalam rentang tertentu.

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

1

Bukan ini

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

Anda harus menggunakan ini

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

Kita harus menggunakan operator Logika bitwise NumPy |, &, ~, ^ untuk kueri penggabungan. Selain itu, tanda kurung penting untuk prioritas operator.

Untuk info lebih lanjut, Anda dapat mengunjungi link: Comparisons, Masks, dan Boolean Logic

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.