Как выбрать строки из DataFrame на основе значений в некотором столбце в Python Pandas?

В SQL я бы использовал:

SELECT *
FROM table
WHERE colume_name = some_value

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

1791
szli 12 Июн 2013 в 21:42

7 ответов

Вот простой пример

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
21
DataByDavid 13 Июн 2013 в 11:49

Больше гибкости, используя .query с pandas >= 0.25.0:

Август 2019 обновленный ответ

Поскольку pandas >= 0.25.0 мы можем использовать метод query для фильтрации информационных кадров с помощью методов pandas и даже имен столбцов с пробелами. Обычно пробелы в именах столбцов приводят к ошибке, но теперь мы можем решить эту проблему с помощью обратного символа (`), см. 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
18
Erfan 4 Авг 2019 в 12:59

Чтобы добавить к этому известному вопросу (хотя и слишком поздно): Вы также можете сделать 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
12
TuanDT 18 Ноя 2016 в 12:10

Вы также можете использовать .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'])]]
5
Vahidn 7 Дек 2018 в 17:38

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

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]]
15
firelynx 22 Июн 2018 в 07:44

Более быстрых результатов можно достичь с помощью 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
23
Brian Burns 3 Окт 2017 в 16:17

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

Воспроизводится с http://pandas.pydata.org/pandas-docs/ версия / 0.17.0 / indexing.html # индексирование -запрос

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')
59
fredcallaway 9 Фев 2016 в 01:36