DataFrame
Python Pandalarda bazı sütunlardaki değerlere dayalı olarak satırlar nasıl seçilir ?
SQL'de kullanacağım:
SELECT *
FROM table
WHERE colume_name = some_value
Panda belgelerine bakmaya çalıştım ama hemen cevabı bulamadım.
DataFrame
Python Pandalarda bazı sütunlardaki değerlere dayalı olarak satırlar nasıl seçilir ?
SQL'de kullanacağım:
SELECT *
FROM table
WHERE colume_name = some_value
Panda belgelerine bakmaya çalıştım ama hemen cevabı bulamadım.
Yanıtlar:
Sütun değeri bir skalere eşit olan satırları seçmek için şunu some_value
kullanın ==
:
df.loc[df['column_name'] == some_value]
Sütun değeri yinelenebilir olan satırları seçmek için şunu some_values
kullanın isin
:
df.loc[df['column_name'].isin(some_values)]
Birden çok koşulu aşağıdakilerle birleştirin &
:
df.loc[(df['column_name'] >= A) & (df['column_name'] <= B)]
Parantezleri not edin. Nedeniyle Python'un için operatör öncelik kuralları , &
bağlamalar daha sıkı daha <=
ve >=
. Bu nedenle, son örnekteki parantezler gereklidir. Parantez olmadan
df['column_name'] >= A & df['column_name'] <= B
olarak ayrıştırılır
df['column_name'] >= (A & df['column_name']) <= B
bir Serinin bir Doğruluk değeri ile sonuçlanan belirsiz bir hatadır .
Sütun değeri eşit olmayan satırları seçmek için şunu some_value
kullanın !=
:
df.loc[df['column_name'] != some_value]
isin
döner bir boolean Serisi, böylece, değeri olduğu satırları seçmek için değil de some_values
kullanarak boolean Serisi boşa, ~
:
df.loc[~df['column_name'].isin(some_values)]
Örneğin,
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'])
verim
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
Eklemek istediğiniz birden fazla değeriniz varsa, bunları bir listeye (veya daha genel olarak, yinelenebilir) koyun ve şunu kullanın isin
:
print(df.loc[df['B'].isin(['one','three'])])
verim
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
Bununla birlikte, bunu birçok kez yapmak istiyorsanız, önce bir dizin oluşturmanın ve ardından şunu kullanmanın daha verimli olduğunu unutmayın df.loc
:
df = df.set_index(['B'])
print(df.loc['one'])
verim
A C D
B
one foo 0 0
one bar 1 2
one foo 6 12
veya dizin kullanımından birden çok değer eklemek için df.index.isin
:
df.loc[df.index.isin(['one','two'])]
verim
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
df.where(condition)
, koşulun şekliyle aynı olmalıdır df
.
df[df['column_name'] == some_value]
eserleri, neden eklemek gerek yok .loc
burada?
Panda veri çerçevesinden satır seçmenin birkaç yolu vardır:
df[df['col'] == value
])df.iloc[...]
)df.xs(...)
)df.query(...)
APIAşağıda, belirli tekniklerin ne zaman kullanılacağına dair tavsiyeyle size her birinden örnekler göstereceğim. Ölçütümüzün sütun 'A'
== olduğunu varsayın'foo'
(Performansla ilgili not: Her taban türü için, panda API'sini kullanarak işleri basit tutabiliriz veya genellikle API'nın dışına girebiliriz numpy
ve genellikle işleri hızlandırırız.)
Kurulum
İhtiyacımız olan ilk şey, satır seçme ölçütümüz olacak bir koşulu tanımlamaktır. OP'nin davasıyla başlayacağız column_name == some_value
ve diğer bazı yaygın kullanım örneklerini de ekleyeceğiz.
@Unutbu'dan borçlanma:
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})
... Boole indekslemesi, her satırın 'A'
sütununun gerçek değerinin eşit olmasını 'foo'
ve ardından hangi satırların saklanacağını belirlemek için bu doğruluk değerlerini kullanmayı gerektirir. Tipik olarak, bu seriyi, doğruluk değerleri dizisi olarak adlandırırız mask
. Bunu burada da yapacağız.
mask = df['A'] == 'foo'
Daha sonra bu maskeyi veri çerçevesini dilimlemek veya dizine eklemek için kullanabiliriz
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
Bu, bu görevi gerçekleştirmenin en basit yollarından biridir ve performans veya sezgisellik bir sorun değilse, bu sizin seçtiğiniz yöntem olmalıdır. Bununla birlikte, performans bir endişe kaynağıysa, oluşturmanın alternatif bir yolunu düşünmek isteyebilirsiniz mask
.
Konumsal indeksleme ( df.iloc[...]
) kullanım örneklerine sahiptir, ancak bu bunlardan biri değildir. Nerede dilimleneceğini belirlemek için, önce yukarıda yaptığımız aynı boole analizini yapmamız gerekir. Bu, aynı görevi yerine getirmek için bir adım daha atmamızı sağlar.
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
Etiket dizine ekleme çok kullanışlı olabilir, ancak bu durumda yine yararsız olarak daha fazla iş yapıyoruz
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
df.query()
APIpd.DataFrame.query
bu görevi gerçekleştirmenin çok zarif / sezgisel bir yoludur, ancak genellikle daha yavaştır. Ancak , aşağıdaki zamanlamalara dikkat ederseniz, büyük veriler için sorgu çok etkilidir. Standart yaklaşımdan daha çok ve en iyi önerim ile aynı büyüklükte.
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
Benim tercihim Boolean
mask
Gerçek iyileştirmeler, bizim yaratma şeklimizi değiştirerek yapılabilir Boolean
mask
.
mask
alternatif 1
Temel numpy
diziyi kullanın ve başka bir tane oluşturma yükünü kaldırınpd.Series
mask = df['A'].values == 'foo'
Sonunda daha eksiksiz zaman testleri göstereceğim, ancak örnek veri çerçevesini kullanarak elde ettiğimiz performans kazançlarına bir göz atın. İlk olarak,mask
%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)
Dizisi mask
ile değerlendirmek numpy
~ 30 kat daha hızlıdır. Bunun nedeni kısmen numpy
değerlendirmenin genellikle daha hızlı olmasıdır. Ayrıca kısmen bir dizin ve karşılık gelen bir pd.Series
nesne oluşturmak için gerekli ek yükün eksikliğinden kaynaklanmaktadır .
Sonra, biriyle diğerine dilimleme zamanlamasına bakacağız mask
.
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)
Performans kazanımları belirgin değildir. Bunun daha sağlam testlere dayanıp dayanmadığını göreceğiz.
mask
alternatif 2
Veri çerçevesini de yeniden inşa edebilirdik. Bir veri çerçevesini yeniden oluştururken büyük bir uyarı var - dtypes
bunu yaparken dikkatli olmalısınız !
Bunun yerine df[mask]
yapacağız
pd.DataFrame(df.values[mask], df.index[mask], df.columns).astype(df.dtypes)
Veri çerçevesi, bizim örneğimiz olan karışık türde ise, df.values
sonuçta elde edilen diziyi aldığımızda dtype
object
ve sonuç olarak, yeni veri çerçevesinin tüm sütunları olacaktır dtype
object
. Böylece astype(df.dtypes)
herhangi bir potansiyel performans kazancı gerektirir ve öldürür.
%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)
Ancak, veri çerçevesi karışık tipte değilse, bunu yapmak için çok yararlı bir yoldur.
verilmiş
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)
Karşı
%%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)
Zamanı yarıya indirdik.
mask
alternatif 3
@ unutbu ayrıca bir değer kümesinde olmanın pd.Series.isin
her bir öğesini hesaba katmanın nasıl kullanılacağını da gösterir df['A']
. Değerlerimiz bir değerden oluşan bir setse, bu aynı şeyi değerlendirir 'foo'
. Ancak, gerekirse daha büyük değer kümeleri eklemeyi de genelleştirir. Görünüşe göre, daha genel bir çözüm olmasına rağmen hala oldukça hızlı. Tek gerçek kayıp, kavrama aşina olmayanlar için sezgiselliktedir.
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
Bununla birlikte, daha önce olduğu gibi, numpy
neredeyse hiçbir şeyden ödün vermeden performansı artırmak için kullanabiliriz . Kullanacağıznp.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
Zamanlama
Referans için diğer yayınlarda belirtilen diğer kavramları da ekleyeceğim.
Aşağıdaki Kod
Bu tablodaki her Sütun, her bir işlevi test ettiğimiz farklı bir uzunluk veri çerçevesini temsil eder. Her sütun, göreli süreyi gösterir ve en hızlı fonksiyonun temel indeksi verilir 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
En hızlı zamanların arasında paylaşıldığını göreceksiniz mask_with_values
vemask_with_in1d
res.T.plot(loglog=True)
Fonksiyonlar
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]
Test yapmak
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)
Özel Zamanlama
Tek bir nesnemiz olmadığında özel duruma bakmakdtype
Tüm veri çerçevesi için .
Aşağıdaki Kod
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
Görünen o ki, yeniden yapılanma birkaç yüz sıradan geçmiyor.
spec.T.plot(loglog=True)
Fonksiyonlar
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
)
Test yapmak
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)
.iloc(numpy.where(..))
bu şemada nasıl karşılaştırılacak? ii) birden fazla koşul kullanırken sıralamaların aynı olmasını bekler misiniz?
pd.Series.isin
, bu not mu kullanımını np.in1d
belirli senaryosunda kaputun altında, kullandığı başkalarında Khash ve örtük belirli durumlarda performansa karşı karma maliyeti arasında bir ticaret-off geçerlidir. Bu cevabın daha fazla detayı var.
[{P|EXP}TIME]
- ve [{C|P|EXP}SPACE]
- maliyetlerle (aynı anda bütün dataframes yukarıdan aşağıya işleme) blok-sözdizimi önerilen formları yukarıda kullanmanın büyümek yani zaman, bazı ~1E6, ~1E9, ~1E12
satır sayılarına mı ölçeklendirildi ? Bize resmin tamamını gösterdiğiniz için teşekkürler, efendim. [min, Avg, MAX, StDev]
Hem min
ve hem de MAX
değerler Mean/StDev
partinin rahatlamasına eşlik ettiğinden, nicel karşılaştırmalı okumalar her zaman memnuniyetle karşılanır .
Pandalar
select * from table where column_name = some_value
dır-dir
table[table.column_name == some_value]
Birden fazla koşul:
table[(table.column_name == some_value) | (table.column_name2 == some_value2)]
veya
table.query('column_name == some_value | column_name2 == some_value2')
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
Yukarıdaki kodda df[df.foo == 222]
, 222
bu durumda sütun değerine göre satır veren satırdır .
Birden fazla koşul da mümkündür:
df[(df.foo == 222) | (df.bar == 444)]
# bar foo
# 1 444 111
# 2 555 222
Ancak bu noktada , daha az ayrıntılı ve aynı sonucu verdiğinden , sorgu işlevini kullanmanızı öneririm :
df.query('foo == 222 | bar == 444')
query
burada yöntem zincirleme ile uyumlu tek cevaptır. Görünüşe göre filter
dplyr içinde pandalar analog .
[
köşeli parantez olmayan köşeli parantezlere ihtiyacınız var (
.
|
AND için olduğunu düşündüm , ama elbette OR-operatörü ...
df[condition1][condition2]
df.query('`my col` == 124')
Önceki cevapların sözdiziminin gereksiz ve hatırlanması zor olduğunu düşünüyorum. Pandalar query()
yöntemi v0.13'te tanıttı ve ben çok tercih ediyorum. Sorunuz için yapabilirdinizdf.query('col == val')
Çoğaltılamaz 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
Ayrıca, üzerindeki bir değişkene başlayarak ortamdaki değişkenlere erişebilirsiniz @
.
exclude = ('red', 'orange')
df.query('color not in @exclude')
numexpr
kurulu olması gerekir.
.query
birlikte daha fazla esneklik pandas >= 0.25.0
:Ağustos 2019 güncellenmiş cevap
Bu yöntemi, veri çerçevelerini panda yöntemleri ve hatta boşluklu sütun adları ile filtrelemek için pandas >= 0.25.0
kullanabiliriz query
. Normalde sütun adlarındaki boşluklar bir hata verir, ancak şimdi bunu bir backtick (`) kullanarak çözebiliriz 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
.query
Yöntemi ile kullanma str.endswith
:
df.query('`Sender email`.str.endswith("@shop.com")')
Çıktı
Sender email
1 reply@shop.com
2 buy@shop.com
Ayrıca sorgumuzda bir ile önek kullanarak yerel değişkenleri kullanabiliriz @
:
domain = 'shop.com'
df.query('`Sender email`.str.endswith(@domain)')
Çıktı
Sender email
1 reply@shop.com
2 buy@shop.com
Numpy.where kullanılarak daha hızlı sonuçlar elde edilebilir .
Örneğin, unubtu kurulumu ile -
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
Zamanlama karşılaştırmaları:
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
İşte basit bir örnek
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
Pandalarda belirli bir değer için yalnızca birden çok sütundan belirli sütunları seçmek için:
select col_name1, col_name2 from table where column_name = some_value.
Seçenekler:
df.loc[df['column_name'] == some_value][[col_name1, col_name2]]
veya
df.query['column_name' == 'some_value'][[col_name1, col_name2]]
Bu ünlü soruya eklemek için (biraz geç olsa da): df.groupby('column_name').get_group('column_desired_value').reset_index()
Belirli bir değere sahip belirtilen sütunla yeni bir veri çerçevesi de yapabilirsiniz . Örneğin
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)
Çalıştır şunu verir:
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
get_group()
otomatik olarak bir veri çerçevesi döndürecektir. Ayrıca bir parametre olarak "drop = True" diyebilirsiniz reset_index()
. Başka bir deyişle, kısaltılabilir: b_is_two_dataframe = df.groupby('B').get_group('two').reset_index(drop=True)
.Apply komutunu da kullanabilirsiniz:
df.apply(lambda row: row[df['B'].isin(['one','three'])])
Aslında satır bazında çalışır (yani, işlevi her satıra uygular).
Çıktı
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
Sonuçlar @unutbu tarafından belirtilenle aynıdır
df[[df['B'].isin(['one','three'])]]