Bagaimana cara memilih baris dari DataFrame berdasarkan nilai kolom?


1963

Bagaimana cara memilih baris dari DataFrameberdasarkan pada beberapa kolom di Python Pandas?

Dalam SQL, saya akan menggunakan:

SELECT *
FROM table
WHERE colume_name = some_value

Saya mencoba melihat dokumentasi panda tetapi tidak segera menemukan jawabannya.



6
Ini adalah perbandingan dengan SQL: pandas.pydata.org/pandas-docs/stable/comparison_with_sql.html di mana Anda dapat menjalankan panda sebagai SQL.
i_thamary

Jawaban:


3771

Untuk memilih baris yang nilai kolomnya sama dengan skalar some_value,, gunakan ==:

df.loc[df['column_name'] == some_value]

Untuk memilih baris yang nilai kolomnya dapat diubah some_values, gunakan isin:

df.loc[df['column_name'].isin(some_values)]

Gabungkan beberapa kondisi dengan &:

df.loc[(df['column_name'] >= A) & (df['column_name'] <= B)]

Perhatikan tanda kurung. Karena aturan prioritas operator Python , &mengikat lebih erat dari <=dan >=. Jadi, tanda kurung dalam contoh terakhir diperlukan. Tanpa tanda kurung

df['column_name'] >= A & df['column_name'] <= B

diuraikan sebagai

df['column_name'] >= (A & df['column_name']) <= B

yang menghasilkan nilai Kebenaran dari suatu Seri adalah kesalahan yang mendua .


Untuk memilih baris yang nilai kolomnya tidak sama some_value , gunakan !=:

df.loc[df['column_name'] != some_value]

isinmengembalikan Seri boolean, jadi untuk memilih baris yang nilainya tidak dalam some_values, negasikan Seri boolean menggunakan ~:

df.loc[~df['column_name'].isin(some_values)]

Sebagai contoh,

import pandas as pd
import numpy as np
df = pd.DataFrame({'A': 'foo bar foo bar foo bar foo foo'.split(),
                   'B': 'one one two three two two one three'.split(),
                   'C': np.arange(8), 'D': np.arange(8) * 2})
print(df)
#      A      B  C   D
# 0  foo    one  0   0
# 1  bar    one  1   2
# 2  foo    two  2   4
# 3  bar  three  3   6
# 4  foo    two  4   8
# 5  bar    two  5  10
# 6  foo    one  6  12
# 7  foo  three  7  14

print(df.loc[df['A'] == 'foo'])

hasil panen

     A      B  C   D
0  foo    one  0   0
2  foo    two  2   4
4  foo    two  4   8
6  foo    one  6  12
7  foo  three  7  14

Jika Anda memiliki beberapa nilai yang ingin Anda sertakan, masukkan ke dalam daftar (atau lebih umum, setiap iterable) dan gunakan isin:

print(df.loc[df['B'].isin(['one','three'])])

hasil panen

     A      B  C   D
0  foo    one  0   0
1  bar    one  1   2
3  bar  three  3   6
6  foo    one  6  12
7  foo  three  7  14

Perhatikan, bagaimanapun, bahwa jika Anda ingin melakukan ini berkali-kali, itu lebih efisien untuk membuat indeks terlebih dahulu, dan kemudian gunakan df.loc:

df = df.set_index(['B'])
print(df.loc['one'])

hasil panen

       A  C   D
B              
one  foo  0   0
one  bar  1   2
one  foo  6  12

atau, untuk memasukkan beberapa nilai dari penggunaan indeks df.index.isin:

df.loc[df.index.isin(['one','two'])]

hasil panen

       A  C   D
B              
one  foo  0   0
one  bar  1   2
two  foo  2   4
two  foo  4   8
two  bar  5  10
one  foo  6  12

19
Bahkan, df [df ['colume_name'] == some_value] juga berfungsi. Tetapi upaya pertama saya, df.where (df ['colume_name'] == some_value) tidak berfungsi ... tidak yakin mengapa ...
szli

13
Saat Anda menggunakan df.where(condition), kondisinya harus memiliki bentuk yang sama df.
unutbu


8
FYI: Jika Anda ingin memilih satu baris berdasarkan pada dua (atau lebih) label (baik yang membutuhkan keduanya atau salah satu), lihat stackoverflow.com/questions/31756340/…
Shane

7
Sejak df[df['column_name'] == some_value]berhasil, mengapa kita perlu menambahkan di .locsini?
qqqwww

314

Ada beberapa cara untuk memilih baris dari bingkai data panda:

  1. Pengindeksan boolean ( df[df['col'] == value])
  2. Pengindeksan posisi ( df.iloc[...])
  3. Pengindeksan label ( df.xs(...))
  4. df.query(...) API

Di bawah ini saya tunjukkan contoh masing-masing, dengan saran kapan harus menggunakan teknik tertentu. Asumsikan kriteria kami adalah kolom 'A'=='foo'

(Catatan tentang kinerja: Untuk setiap jenis basis, kita dapat menjaga hal-hal sederhana dengan menggunakan API panda atau kita dapat menjelajah di luar API, biasanya ke dalam numpy, dan mempercepatnya.)


Pengaturan
Hal pertama yang kita perlukan adalah mengidentifikasi suatu kondisi yang akan bertindak sebagai kriteria kita untuk memilih baris. Kami akan mulai dengan kasus OP column_name == some_value, dan menyertakan beberapa kasus penggunaan umum lainnya.

Meminjam dari @unutbu:

import pandas as pd, numpy as np

df = pd.DataFrame({'A': 'foo bar foo bar foo bar foo foo'.split(),
                   'B': 'one one two three two two one three'.split(),
                   'C': np.arange(8), 'D': np.arange(8) * 2})

1. Pengindeksan Boolean

... Pengindeksan boolean membutuhkan menemukan nilai sebenarnya dari setiap 'A'kolom baris yang sama 'foo', kemudian menggunakan nilai-nilai kebenaran untuk mengidentifikasi baris mana yang harus dipertahankan. Biasanya, kami akan menamai seri ini, array nilai kebenaran mask,. Kami akan melakukannya di sini juga.

mask = df['A'] == 'foo'

Kami kemudian dapat menggunakan topeng ini untuk mengiris atau mengindeks bingkai data

df[mask]

     A      B  C   D
0  foo    one  0   0
2  foo    two  2   4
4  foo    two  4   8
6  foo    one  6  12
7  foo  three  7  14

Ini adalah salah satu cara paling sederhana untuk menyelesaikan tugas ini dan jika kinerja atau intuitifitas tidak menjadi masalah, ini harus menjadi metode yang Anda pilih. Namun, jika kinerja merupakan masalah, maka Anda mungkin ingin mempertimbangkan cara alternatif untuk membuatnya mask.


2. Pengindeksan posisi

Pengindeksan posisi ( df.iloc[...]) memiliki kasus penggunaannya, tetapi ini bukan salah satunya. Untuk mengidentifikasi di mana harus mengiris, pertama-tama kita perlu melakukan analisis boolean yang sama seperti yang kita lakukan di atas. Ini membuat kami melakukan satu langkah ekstra untuk menyelesaikan tugas yang sama.

mask = df['A'] == 'foo'
pos = np.flatnonzero(mask)
df.iloc[pos]

     A      B  C   D
0  foo    one  0   0
2  foo    two  2   4
4  foo    two  4   8
6  foo    one  6  12
7  foo  three  7  14

3. Pengindeksan label

Pengindeksan label bisa sangat berguna, tetapi dalam hal ini, kami kembali melakukan lebih banyak pekerjaan tanpa manfaat

df.set_index('A', append=True, drop=False).xs('foo', level=1)

     A      B  C   D
0  foo    one  0   0
2  foo    two  2   4
4  foo    two  4   8
6  foo    one  6  12
7  foo  three  7  14

4. df.query()API

pd.DataFrame.queryadalah cara yang sangat elegan / intuitif untuk melakukan tugas ini, tetapi seringkali lebih lambat. Namun , jika Anda memperhatikan timing di bawah ini, untuk data besar, kueri ini sangat efisien. Lebih dari pendekatan standar dan besarnya serupa sebagai saran terbaik saya.

df.query('A == "foo"')

     A      B  C   D
0  foo    one  0   0
2  foo    two  2   4
4  foo    two  4   8
6  foo    one  6  12
7  foo  three  7  14

Preferensi saya adalah menggunakan Boolean mask

Perbaikan yang sebenarnya dapat dilakukan dengan memodifikasi cara kami membuat Boolean mask.

maskalternatif 1
Gunakan numpyarray yang mendasari dan lupakan overhead untuk membuat yang lainpd.Series

mask = df['A'].values == 'foo'

Saya akan menunjukkan tes waktu yang lebih lengkap di bagian akhir, tetapi lihat saja peningkatan kinerja yang kami dapatkan menggunakan kerangka data sampel. Pertama, kita melihat perbedaan dalam menciptakanmask

%timeit mask = df['A'].values == 'foo'
%timeit mask = df['A'] == 'foo'

5.84 µs ± 195 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
166 µs ± 4.45 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

Mengevaluasi maskdengan numpyarray adalah ~ 30 kali lebih cepat. Ini sebagian karena numpyevaluasi sering lebih cepat. Ini juga sebagian karena kurangnya overhead yang diperlukan untuk membangun indeks dan pd.Seriesobjek yang sesuai .

Selanjutnya, kita akan melihat waktu untuk mengiris dengan yang satu maskversus yang lain.

mask = df['A'].values == 'foo'
%timeit df[mask]
mask = df['A'] == 'foo'
%timeit df[mask]

219 µs ± 12.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
239 µs ± 7.03 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

Keuntungan kinerja tidak diucapkan. Kita akan melihat apakah ini tahan terhadap pengujian yang lebih kuat.


maskalternatif 2
Kita bisa merekonstruksi bingkai data juga. Ada peringatan besar ketika merekonstruksi kerangka data — Anda harus berhati-hati dtypesketika melakukannya!

Alih-alih df[mask]kita akan melakukan ini

pd.DataFrame(df.values[mask], df.index[mask], df.columns).astype(df.dtypes)

Jika bingkai data adalah tipe campuran, yang merupakan contoh kita, maka ketika kita mendapatkan df.valuesarray yang dihasilkan adalah dtype objectdan akibatnya, semua kolom dari bingkai data baru akan menjadi dtype object. Dengan demikian membutuhkan astype(df.dtypes)dan membunuh keuntungan kinerja potensial.

%timeit df[m]
%timeit pd.DataFrame(df.values[mask], df.index[mask], df.columns).astype(df.dtypes)

216 µs ± 10.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
1.43 ms ± 39.6 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

Namun, jika frame data bukan tipe campuran, ini adalah cara yang sangat berguna untuk melakukannya.

Diberikan

np.random.seed([3,1415])
d1 = pd.DataFrame(np.random.randint(10, size=(10, 5)), columns=list('ABCDE'))

d1

   A  B  C  D  E
0  0  2  7  3  8
1  7  0  6  8  6
2  0  2  0  4  9
3  7  3  2  4  3
4  3  6  7  7  4
5  5  3  7  5  9
6  8  7  6  4  7
7  6  2  6  6  5
8  2  8  7  5  8
9  4  7  6  1  5    

%%timeit
mask = d1['A'].values == 7
d1[mask]

179 µs ± 8.73 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

Melawan

%%timeit
mask = d1['A'].values == 7
pd.DataFrame(d1.values[mask], d1.index[mask], d1.columns)

87 µs ± 5.12 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

Kami memotong waktu menjadi dua.


maskalternatif 3
@unutbu juga menunjukkan kepada kita cara menggunakan pd.Series.isinuntuk memperhitungkan setiap elemen df['A']dalam serangkaian nilai. Ini mengevaluasi ke hal yang sama jika set nilai kami adalah satu set nilai, yaitu 'foo'. Tetapi juga menggeneralisasi untuk memasukkan set nilai yang lebih besar jika diperlukan. Ternyata, ini masih cukup cepat walaupun itu adalah solusi yang lebih umum. Satu-satunya kerugian nyata adalah pada intuisi bagi mereka yang tidak terbiasa dengan konsep tersebut.

mask = df['A'].isin(['foo'])
df[mask]

     A      B  C   D
0  foo    one  0   0
2  foo    two  2   4
4  foo    two  4   8
6  foo    one  6  12
7  foo  three  7  14

Namun, seperti sebelumnya, kita dapat memanfaatkan numpyuntuk meningkatkan kinerja tanpa mengorbankan apa pun. Kami akan gunakannp.in1d

mask = np.in1d(df['A'].values, ['foo'])
df[mask]

     A      B  C   D
0  foo    one  0   0
2  foo    two  2   4
4  foo    two  4   8
6  foo    one  6  12
7  foo  three  7  14

Waktu
saya akan menyertakan konsep lain yang disebutkan dalam posting lain juga untuk referensi.
Kode di bawah ini

Setiap kolom dalam tabel ini mewakili kerangka data panjang yang berbeda di mana kami menguji setiap fungsi. Setiap kolom menunjukkan waktu relatif yang diambil, dengan fungsi tercepat diberi indeks dasar 1.0.

res.div(res.min())

                         10        30        100       300       1000      3000      10000     30000
mask_standard         2.156872  1.850663  2.034149  2.166312  2.164541  3.090372  2.981326  3.131151
mask_standard_loc     1.879035  1.782366  1.988823  2.338112  2.361391  3.036131  2.998112  2.990103
mask_with_values      1.010166  1.000000  1.005113  1.026363  1.028698  1.293741  1.007824  1.016919
mask_with_values_loc  1.196843  1.300228  1.000000  1.000000  1.038989  1.219233  1.037020  1.000000
query                 4.997304  4.765554  5.934096  4.500559  2.997924  2.397013  1.680447  1.398190
xs_label              4.124597  4.272363  5.596152  4.295331  4.676591  5.710680  6.032809  8.950255
mask_with_isin        1.674055  1.679935  1.847972  1.724183  1.345111  1.405231  1.253554  1.264760
mask_with_in1d        1.000000  1.083807  1.220493  1.101929  1.000000  1.000000  1.000000  1.144175

Anda akan melihat bahwa waktu tercepat tampaknya dibagi antara mask_with_valuesdanmask_with_in1d

res.T.plot(loglog=True)

masukkan deskripsi gambar di sini

Fungsi

def mask_standard(df):
    mask = df['A'] == 'foo'
    return df[mask]

def mask_standard_loc(df):
    mask = df['A'] == 'foo'
    return df.loc[mask]

def mask_with_values(df):
    mask = df['A'].values == 'foo'
    return df[mask]

def mask_with_values_loc(df):
    mask = df['A'].values == 'foo'
    return df.loc[mask]

def query(df):
    return df.query('A == "foo"')

def xs_label(df):
    return df.set_index('A', append=True, drop=False).xs('foo', level=-1)

def mask_with_isin(df):
    mask = df['A'].isin(['foo'])
    return df[mask]

def mask_with_in1d(df):
    mask = np.in1d(df['A'].values, ['foo'])
    return df[mask]

Pengujian

res = pd.DataFrame(
    index=[
        'mask_standard', 'mask_standard_loc', 'mask_with_values', 'mask_with_values_loc',
        'query', 'xs_label', 'mask_with_isin', 'mask_with_in1d'
    ],
    columns=[10, 30, 100, 300, 1000, 3000, 10000, 30000],
    dtype=float
)

for j in res.columns:
    d = pd.concat([df] * j, ignore_index=True)
    for i in res.index:a
        stmt = '{}(d)'.format(i)
        setp = 'from __main__ import d, {}'.format(i)
        res.at[i, j] = timeit(stmt, setp, number=50)

Penentuan Waktu Khusus
Melihat kasus khusus ketika kami memiliki satu non-objek dtypeuntuk seluruh bingkai data. Kode di bawah ini

spec.div(spec.min())

                     10        30        100       300       1000      3000      10000     30000
mask_with_values  1.009030  1.000000  1.194276  1.000000  1.236892  1.095343  1.000000  1.000000
mask_with_in1d    1.104638  1.094524  1.156930  1.072094  1.000000  1.000000  1.040043  1.027100
reconstruct       1.000000  1.142838  1.000000  1.355440  1.650270  2.222181  2.294913  3.406735

Ternyata, rekonstruksi tidak layak melewati beberapa ratus baris.

spec.T.plot(loglog=True)

masukkan deskripsi gambar di sini

Fungsi

np.random.seed([3,1415])
d1 = pd.DataFrame(np.random.randint(10, size=(10, 5)), columns=list('ABCDE'))

def mask_with_values(df):
    mask = df['A'].values == 'foo'
    return df[mask]

def mask_with_in1d(df):
    mask = np.in1d(df['A'].values, ['foo'])
    return df[mask]

def reconstruct(df):
    v = df.values
    mask = np.in1d(df['A'].values, ['foo'])
    return pd.DataFrame(v[mask], df.index[mask], df.columns)

spec = pd.DataFrame(
    index=['mask_with_values', 'mask_with_in1d', 'reconstruct'],
    columns=[10, 30, 100, 300, 1000, 3000, 10000, 30000],
    dtype=float
)

Pengujian

for j in spec.columns:
    d = pd.concat([df] * j, ignore_index=True)
    for i in spec.index:
        stmt = '{}(d)'.format(i)
        setp = 'from __main__ import d, {}'.format(i)
        spec.at[i, j] = timeit(stmt, setp, number=50)

6
Jawaban yang fantastis! 2 pertanyaan, i) bagaimana .iloc(numpy.where(..))membandingkan dalam skema ini? ii) apakah Anda berharap peringkatnya sama ketika menggunakan beberapa kondisi?
posdef

3
Untuk kinerja pd.Series.isin, catatan itu tidak digunakan np.in1ddi bawah tenda dalam skenario tertentu, penggunaan Khash pada orang lain, dan secara implisit menerapkan trade-off antara biaya hashing terhadap kinerja dalam situasi tertentu. Jawaban ini lebih detail.
jpp

1
Pada 9 screenfuls, ini adalah cara yang berlebihan untuk pengguna baru atau bahkan perantara. Anda dapat dan harus meringkas sendiri tl; dr pada paragraf pertama.
smci

@piRSquared Masalah Penskalaan Maukah Anda, @piRSquared, untuk juga memposting pengalaman Anda tentang seberapa baik sebenarnya [{P|EXP}TIME] - dan [{C|P|EXP}SPACE]- biaya penggunaan bentuk-bentuk blok-sintaks yang diusulkan di atas (memproses top-down seluruh dataframe sekaligus) tumbuh , yaitu ketika diskalakan ke beberapa ~1E6, ~1E9, ~1E12jumlah baris? Terima kasih telah menunjukkan kepada kami seluruh gambar, Pak. Bacaan patokan kuantitatif dengan [min, Avg, MAX, StDev]selalu diterima, karena baik mindan MAXnilai - nilai menyertai Mean/StDevrelief batch.
user3666197

Jawaban yang sangat bagus! Permintaan memecahkan masalah saya!
Pavlos Ponos

281

tl; dr

Panda setara dengan

select * from table where column_name = some_value

adalah

table[table.column_name == some_value]

Beberapa kondisi:

table[(table.column_name == some_value) | (table.column_name2 == some_value2)]

atau

table.query('column_name == some_value | column_name2 == some_value2')

Contoh kode

import pandas as pd

# Create data set
d = {'foo':[100, 111, 222], 
     'bar':[333, 444, 555]}
df = pd.DataFrame(d)

# Full dataframe:
df

# Shows:
#    bar   foo 
# 0  333   100
# 1  444   111
# 2  555   222

# Output only the row(s) in df where foo is 222:
df[df.foo == 222]

# Shows:
#    bar  foo
# 2  555  222

Dalam kode di atas itu adalah baris df[df.foo == 222]yang memberikan baris berdasarkan nilai kolom, 222dalam hal ini.

Berbagai kondisi juga dimungkinkan:

df[(df.foo == 222) | (df.bar == 444)]
#    bar  foo
# 1  444  111
# 2  555  222

Tetapi pada saat itu saya akan merekomendasikan menggunakan fungsi kueri , karena kurang verbose dan menghasilkan hasil yang sama:

df.query('foo == 222 | bar == 444')

5
queryadalah satu-satunya jawaban di sini yang kompatibel dengan metode chaining. Sepertinya itu analog panda ke filterdalam dplyr.
Berk U.

3
Hai, dalam contoh ketiga Anda (beberapa kolom) Saya pikir Anda perlu tanda kurung siku [tidak bulat tanda kurung (di luar.
user2739472

2
pada awalnya saya pikir |itu untuk DAN, tapi tentu saja itu OR-operator ...
O-9

untuk beberapa kondisi menggunakan AND, bisa dilakukandf[condition1][condition2]
Ritwik

1
Meninggalkan ini di sini untuk berjaga-jaga jika berguna bagi seseorang: mulai dari 0,25 kueri dapat digunakan dengan nama kolom yang memiliki spasi dalam nama dengan melampirkan nama dalam backticks:df.query('`my col` == 124')
cs95

65

Saya menemukan sintaks dari jawaban sebelumnya menjadi redundan dan sulit diingat. Panda memperkenalkan query()metode ini di v0.13 dan saya lebih menyukainya. Untuk pertanyaan Anda, Anda bisa melakukannyadf.query('col == val')

Direproduksi dari http://pandas.pydata.org/pandas-docs/version/0.17.0/indexing.html#indexing-query

In [167]: n = 10

In [168]: df = pd.DataFrame(np.random.rand(n, 3), columns=list('abc'))

In [169]: df
Out[169]: 
          a         b         c
0  0.687704  0.582314  0.281645
1  0.250846  0.610021  0.420121
2  0.624328  0.401816  0.932146
3  0.011763  0.022921  0.244186
4  0.590198  0.325680  0.890392
5  0.598892  0.296424  0.007312
6  0.634625  0.803069  0.123872
7  0.924168  0.325076  0.303746
8  0.116822  0.364564  0.454607
9  0.986142  0.751953  0.561512

# pure python
In [170]: df[(df.a < df.b) & (df.b < df.c)]
Out[170]: 
          a         b         c
3  0.011763  0.022921  0.244186
8  0.116822  0.364564  0.454607

# query
In [171]: df.query('(a < b) & (b < c)')
Out[171]: 
          a         b         c
3  0.011763  0.022921  0.244186
8  0.116822  0.364564  0.454607

Anda juga dapat mengakses variabel di lingkungan dengan menambahkan sebuah @.

exclude = ('red', 'orange')
df.query('color not in @exclude')

1
Anda hanya perlu numexprmenginstal paket .
MERose

4
Dalam kasus saya, saya perlu kutip karena val adalah string. df.query ('col == "val"')
smerlung

28

Fleksibilitas menggunakan .querydengan pandas >= 0.25.0:

Agustus 2019 jawaban diperbarui

Karena pandas >= 0.25.0kita dapat menggunakan querymetode untuk memfilter dataframe dengan metode panda dan bahkan nama kolom yang memiliki spasi. Biasanya spasi dalam nama kolom akan memberikan kesalahan, tetapi sekarang kita dapat menyelesaikannya dengan menggunakan backtick (`) lihat GitHub :

# Example dataframe
df = pd.DataFrame({'Sender email':['ex@example.com', "reply@shop.com", "buy@shop.com"]})

     Sender email
0  ex@example.com
1  reply@shop.com
2    buy@shop.com

Menggunakan .querydengan metode str.endswith:

df.query('`Sender email`.str.endswith("@shop.com")')

Keluaran

     Sender email
1  reply@shop.com
2    buy@shop.com

Kami juga dapat menggunakan variabel lokal dengan mengawali dengan @dalam permintaan kami:

domain = 'shop.com'
df.query('`Sender email`.str.endswith(@domain)')

Keluaran

     Sender email
1  reply@shop.com
2    buy@shop.com

26

Hasil lebih cepat bisa dicapai menggunakan numpy.where .

Misalnya, dengan pengaturan unubtu -

In [76]: df.iloc[np.where(df.A.values=='foo')]
Out[76]: 
     A      B  C   D
0  foo    one  0   0
2  foo    two  2   4
4  foo    two  4   8
6  foo    one  6  12
7  foo  three  7  14

Perbandingan waktu:

In [68]: %timeit df.iloc[np.where(df.A.values=='foo')]  # fastest
1000 loops, best of 3: 380 µs per loop

In [69]: %timeit df.loc[df['A'] == 'foo']
1000 loops, best of 3: 745 µs per loop

In [71]: %timeit df.loc[df['A'].isin(['foo'])]
1000 loops, best of 3: 562 µs per loop

In [72]: %timeit df[df.A=='foo']
1000 loops, best of 3: 796 µs per loop

In [74]: %timeit df.query('(A=="foo")')  # slowest
1000 loops, best of 3: 1.71 ms per loop

24

Ini adalah contoh sederhana

from pandas import DataFrame

# Create data set
d = {'Revenue':[100,111,222], 
     'Cost':[333,444,555]}
df = DataFrame(d)


# mask = Return True when the value in column "Revenue" is equal to 111
mask = df['Revenue'] == 111

print mask

# Result:
# 0    False
# 1     True
# 2    False
# Name: Revenue, dtype: bool


# Select * FROM df WHERE Revenue = 111
df[mask]

# Result:
#    Cost    Revenue
# 1  444     111

17

Untuk memilih hanya kolom tertentu dari beberapa kolom untuk nilai yang diberikan dalam panda:

select col_name1, col_name2 from table where column_name = some_value.

Pilihan:

df.loc[df['column_name'] == some_value][[col_name1, col_name2]]

atau

df.query['column_name' == 'some_value'][[col_name1, col_name2]]

16

Untuk menambahkan pertanyaan terkenal ini (meskipun agak terlambat): Anda juga dapat melakukan df.groupby('column_name').get_group('column_desired_value').reset_index()untuk membuat bingkai data baru dengan kolom yang ditentukan memiliki nilai tertentu. Misalnya

import pandas as pd
df = pd.DataFrame({'A': 'foo bar foo bar foo bar foo foo'.split(),
                   'B': 'one one two three two two one three'.split()})
print("Original dataframe:")
print(df)

b_is_two_dataframe = pd.DataFrame(df.groupby('B').get_group('two').reset_index()).drop('index', axis = 1) 
#NOTE: the final drop is to remove the extra index column returned by groupby object
print('Sub dataframe where B is two:')
print(b_is_two_dataframe)

Jalankan ini memberi:

Original dataframe:
     A      B
0  foo    one
1  bar    one
2  foo    two
3  bar  three
4  foo    two
5  bar    two
6  foo    one
7  foo  three
Sub dataframe where B is two:
     A    B
0  foo  two
1  foo  two
2  bar  two

Jawaban yang bagus Hanya ingin menambahkan bahwa yang kedua (pd.DataFrame) berlebihan karena get_group()akan secara otomatis mengembalikan dataframe. Anda juga bisa mengatakan "drop = True" sebagai parameter reset_index(). Dengan kata lain, dapat disingkat menjadi: b_is_two_dataframe = df.groupby('B').get_group('two').reset_index(drop=True)
Mountain Scott

7

Anda juga dapat menggunakan .apply:

df.apply(lambda row: row[df['B'].isin(['one','three'])])

Ini benar-benar berfungsi baris-bijaksana (yaitu, menerapkan fungsi ke setiap baris).

Outputnya adalah

   A      B  C   D
0  foo    one  0   0
1  bar    one  1   2
3  bar  three  3   6
6  foo    one  6  12
7  foo  three  7  14

Hasilnya sama dengan menggunakan seperti yang disebutkan oleh @unutbu

df[[df['B'].isin(['one','three'])]]
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.