Як вибрати рядки з DataFrame на основі значень стовпців?


1953

Як вибрати рядки на DataFrameоснові значень у деякому стовпці в Python Pandas?

У SQL я б використовував:

SELECT *
FROM table
WHERE colume_name = some_value

Я спробував переглянути документацію панд, але не одразу знайшов відповідь.



6
Це порівняння з SQL: pandas.pydata.org/pandas-docs/stable/comppare_with_sql.html, де можна запускати панди як SQL.
i_thamary

Відповіді:


3761

Щоб вибрати рядки, значення стовпців яких дорівнює скаляру some_value, використовуйте ==:

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

Щоб вибрати рядки, значення стовпців яких є ітерабельним,, some_valuesвикористовуйте isin:

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

Поєднайте кілька умов із &:

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

Зверніть увагу на дужки. Завдяки правилам пріоритетності оператора Python , &зв'язується більш щільно, ніж <=та >=. Таким чином, дужки в останньому прикладі необхідні. Без дужок

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

розбирається як

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

що призводить до істинного значення серії, є неоднозначною помилкою .


Щоб вибрати рядки, значення стовпців яких не дорівнює some_value , використовуйте !=:

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

isinповертає логічне значення серії, тому , щоб вибрати рядки , в яких значення НЕ в some_values, звести на немає булева Series з допомогою ~:

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

Наприклад,

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

врожайність

     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

Якщо у вас є кілька значень, які ви хочете включити, покладіть їх у список (або загалом, будь-який ітерабельний) та використовуйте isin:

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

врожайність

     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

Однак зауважте, що якщо ви хочете зробити це багато разів, то ефективніше спершу зробити індекс, а потім скористатися df.loc:

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

врожайність

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

або, щоб включити кілька значень від використання індексу df.index.isin:

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

врожайність

       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
Насправді, також працює df [df ['colume_name'] == деяке значення]. Але моя перша спроба, df.where (df ['colume_name'] == some_value) не працює ... не впевнений, чому ...
szli

13
Під час використання df.where(condition)умова повинна мати таку ж форму, що і df.
unutbu

3
Ці посилання можуть бути дуже корисні для багатьох з вас: pandas.pydata.org/pandas-docs/stable/indexing.html gregreda.com/2013/10/26/working-with-pandas-dataframes
tremendows

8
FYI: Якщо ви хочете , щоб вибрати рядок , засновану на двох (або більше) етикетки (або вимагають обидва або) см stackoverflow.com/questions/31756340 / ...
Шейн

7
Оскільки df[df['column_name'] == some_value]працює, навіщо нам .locтут додавати ?
qqqwww

311

Існує кілька способів вибору рядків з кадру даних панди:

  1. Булева індексація ( df[df['col'] == value])
  2. Позиційна індексація ( df.iloc[...])
  3. Індексація міток ( df.xs(...))
  4. df.query(...) API

Нижче я показую вам приклади кожного з порадами, коли використовувати певні методики. Припустимо, нашим критерієм є стовпець 'A'=='foo'

(Примітка щодо продуктивності. Для кожного базового типу ми можемо робити прості речі за допомогою API панд або ми можемо виходити за межі API, як правило numpy, і прискорювати роботу.)


Налаштування
Перше, що нам знадобиться - це визначити умову, яка буде виступати нашим критерієм для вибору рядків. Почнемо з справи ОП column_name == some_valueта включимо деякі інші випадки загального використання.

Запозичення від @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. Булева індексація

... Булева індексація вимагає знайти справжнє значення 'A'стовпця кожного рядка рівним 'foo', а потім використовувати ці значення істини, щоб визначити, які рядки потрібно зберегти. Як правило, ми б назвати цю серію, масив значень істинності mask. Ми зробимо це і тут.

mask = df['A'] == '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

Це один із найпростіших способів виконання цього завдання, і якщо продуктивність чи інтуїтивність не є проблемою, це повинен бути обраний вами метод. Однак якщо продуктивність викликає занепокоєння, то, можливо, ви захочете розглянути альтернативний спосіб створення mask.


2. Позиційна індексація

Позиційна індексація ( df.iloc[...]) має свої випадки використання, але це не один із них. Для того, щоб визначити, куди слід нарізати, спочатку нам потрібно провести той же булевий аналіз, який ми робили вище. Це дозволяє нам виконати один додатковий крок для виконання того ж завдання.

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. Індексація міток

Індексація міток може бути дуже зручною, але в цьому випадку ми знову робимо більше роботи без користі

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.queryце дуже елегантний / інтуїтивний спосіб виконання цього завдання, але часто повільніше. Однак якщо ви звернете увагу на терміни, наведені нижче, для великих даних запит є дуже ефективним. Більше, ніж стандартний підхід і такої ж величини, як моя найкраща пропозиція.

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

Моя перевага - використовувати Boolean mask

Фактичні покращення можна зробити, змінивши те, як ми створюємо своє Boolean mask.

maskальтернатива 1
Використовуйте базовий numpyмасив і відмовляйтеся від накладних коштів створення іншогоpd.Series

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

У кінці я покажу більш повні тести часу, але лише погляньте на підвищення продуктивності, який ми отримуємо, використовуючи зразок кадру даних. Спочатку ми розглядаємо різницю у створенні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)

Оцінка масиву maskз numpyмасивом ~ 30 разів швидше. Частково це пов'язано з тим, що numpyоцінка часто буває швидшою. Частково це також зумовлено відсутністю накладних витрат, необхідних для побудови індексу та відповідного pd.Seriesоб'єкта.

Далі ми розглянемо терміни нарізки однієї 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)

Підвищення продуктивності не так виражене. Ми побачимо, чи не витримає це більш надійне тестування.


maskальтернатива 2
Ми могли б також реконструювати кадр даних. Існує велике застереження при реконструкції фрейму даних - ви повинні подбати про те, dtypesколи це робите!

Замість цього df[mask]ми зробимо це

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

Якщо кадр даних змішаного типу, що є нашим прикладом, тоді, коли ми отримуємо df.valuesрезультуючий масив, dtype objectі, отже, всі стовпці нового кадру даних будуть мати dtype object. Таким чином, вимагають astype(df.dtypes)і вбивають будь-які потенційні підвищення продуктивності.

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

Однак якщо кадр даних не змішаного типу, це дуже корисний спосіб зробити це.

Дано

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)

Проти

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

Ми скорочуємо час навпіл.


maskАльтернатива 3
@unutbu також показує нам, як використовувати pd.Series.isinдля обліку кожного елемента, df['A']що знаходиться в наборі значень. Це визначає те саме, якщо наш набір значень є набором одного значення, а саме 'foo'. Але він також узагальнює, якщо потрібно, включати більші набори значень. Виявляється, це все ще досить швидко, хоча це більш загальне рішення. Єдина реальна втрата - це інтуїтивність для тих, хто не знайомий з цією концепцією.

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

Однак, як і раніше, ми можемо використати numpyдля підвищення продуктивності, при цьому не жертвуючи практично нічого. Ми використаємоnp.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

Терміни
Я включатиму інші поняття, згадані в інших посадах, а також для довідок.
Код нижче

Кожен стовпець у цій таблиці являє собою кадр даних різної довжини, на якому ми перевіряємо кожну функцію. Кожен стовпець показує відносний час, зайнятий, при цьому найшвидша функція задається базовим індексом 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

Ви помітите, що швидкий час, здається, ділиться між mask_with_valuesтаmask_with_in1d

res.T.plot(loglog=True)

введіть тут опис зображення

Функції

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]

Тестування

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)

Спеціальні терміни
Дивлячись на особливий випадок, коли у нас є один не-об’єкт dtypeдля всього кадру даних. Код нижче

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

Виявляється, реконструкція не варта цього декількох сотень рядів.

spec.T.plot(loglog=True)

введіть тут опис зображення

Функції

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
)

Тестування

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
Фантастична відповідь! 2 питання, хоча, i) як би .iloc(numpy.where(..))порівняти в цій схемі? ii) Чи очікуєте ви, що рейтинг буде однаковим при використанні декількох умов?
posdef

3
Для виконання pd.Series.isin, зверніть увагу , що робить використання np.in1dпід капотом в конкретному сценарії використання Хаш в інших, і неявно застосовується компроміс між вартістю хеширования по порівнянні з продуктивністю в конкретних ситуаціях. У цій відповіді детальніше.
jpp

1
У 9 екранах це спосіб перевантаження нового або навіть проміжного користувача. Ви можете і повинні самостійно узагальнити tl; dr в першому пункті.
smci

@piRSquared Scaling питання ви НЕ заперечуєте, @piRSquared, також розмістити свій досвід про те , як добре фактичні [{P|EXP}TIME] - і [{C|P|EXP}SPACE]- витрати використання вище запропонованих форм блок-синтаксису (обробка зверху вниз за все dataframes відразу) ростуть , а саме , коли масштабується до деяких ~1E6, ~1E9, ~1E12підрахунків рядків? Дякуємо, що показали нам всю картину, сер. Кількісні показання еталону з [min, Avg, MAX, StDev]завжди вітаються, оскільки minі MAXзначення, і значення супроводжують Mean/StDevрельєф партії.
user3666197

Відмінна відповідь! Запит вирішив мою проблему!
Павлос Понос

280

тл; д-р

Панди, еквівалентні

select * from table where column_name = some_value

є

table[table.column_name == some_value]

Кілька умов:

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

або

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

У наведеному вище коді це рядок, df[df.foo == 222]який дає рядки на основі значення стовпця, 222в цьому випадку.

Також можливі кілька умов:

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

Але в цей момент я рекомендую використовувати функцію запиту , оскільки вона є менш багатослівною і дає такий же результат:

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

5
queryтут єдина відповідь, яка сумісна з ланцюжком методів. Схоже, це аналог панди filterу dplyr.
Берк У.

3
Привіт, у вашому третьому прикладі (кілька стовпців) я думаю, що вам потрібні квадратні дужки, а [не круглі дужки (зовні.
користувач2739472

2
спочатку я думав, що |це для AND, але, звичайно, це АБО-оператор ...
O-9

для декількох умов з допомогою AND, можна зробитиdf[condition1][condition2]
Ritwik

1
Залишаючи це тут лише на випадок, коли комусь це корисно: з 0,25 запиту можна використовувати імена стовпців, які мають пробіли в імені, додаючи ім’я в df.query('`my col` == 124')
беккетки

65

Я вважаю, що синтаксис попередніх відповідей є зайвим і важко запам'ятовується. Pandas ввів query()метод у v0.13, і я його більше віддаю перевагу. Що стосується вашого питання, ви могли б зробитиdf.query('col == val')

Відтворено з 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

Ви також можете отримати доступ до змінних у середовищі, попередньо додавши до нього @.

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

1
Вам потрібен лише numexprвстановлений пакет .
MERose

4
У моєму випадку мені була потрібна цитата, оскільки val - це рядок. df.query ('col == "val"')
smerlung

28

Більш гнучкість використання за .queryдопомогою pandas >= 0.25.0:

Серпень 2019 оновлена ​​відповідь

Оскільки pandas >= 0.25.0ми можемо використовувати queryметод для фільтрації фреймів даних методами pandas і навіть іменами стовпців, які мають пробіли. Зазвичай пробіли у назвах стовпців дають помилку, але тепер ми можемо вирішити це за допомогою backtick (`) див. 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методу str.endswith:

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

Вихідні дані

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

Також ми можемо використовувати локальні змінні, префіксуючи їх @в запиті:

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

Вихідні дані

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

26

Швидші результати можна досягти, використовуючи numpy.where .

Наприклад, із налаштуванням 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

Порівняння часу:

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

Ось простий приклад

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

Для вибору лише певних стовпців із кількох стовпців для заданого значення в пандах:

select col_name1, col_name2 from table where column_name = some_value.

Параметри:

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

або

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

16

Щоб додати це відоме запитання (хоч і трохи пізно): Ви також df.groupby('column_name').get_group('column_desired_value').reset_index()можете зробити новий кадр даних із вказаним стовпцем, який має конкретне значення. Напр

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)

Виконати це дає:

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

Чудова відповідь. Просто хочеться додати, що другий (pd.DataFrame) є зайвим, оскільки get_group()автоматично поверне фрейм даних. Також ви можете просто сказати "drop = True" як параметр reset_index(). Іншими словами, його можна скоротити до: b_is_two_dataframe = df.groupby('B').get_group('two').reset_index(drop=True)
Маунт-Скотт

7

Ви також можете використовувати .apply:

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

Він фактично працює в рядковому порядку (тобто застосовує функцію до кожного рядка).

Вихід є

   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

Результати такі ж, як і використання, як згадувало @unutbu

df[[df['B'].isin(['one','three'])]]
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.