условию - python data frame filter




Выберите строки из DataFrame на основе значений в столбце в пандах (8)

ТЛ; др

Панды, эквивалентные

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

Но в этот момент я бы рекомендовал использовать функцию query , так как он менее подробный и дает тот же результат:

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

Как выбрать строки из DataFrame на основе значений в некоторых столбцах в пандах?
В SQL я бы использовал:

select * from table where colume_name = some_value. 

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


Более быстрые результаты могут быть достигнуты с помощью 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

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

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

Если вы пришли сюда, чтобы выбрать строки из фреймворка данных, включив те, чье значение столбца НЕ является ни одним из списков значений, вот как перевернуть ответ unutbu для списка значений выше:

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

(Чтобы не включать одно значение, конечно, вы просто используете обычный оператор не равно != .)

Пример:

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(df)

дает нам

     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    

Подмножество только для тех строк, которые НЕ являются one или three в столбце B :

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

доходность

     A    B
2  foo  two
4  foo  two
5  bar  two

Чтобы выбрать строки, значение столбца которых равно скаляру, 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'] == some_value) & df['other_column'].isin(some_values)]

Чтобы выбрать строки, значение столбца которых не равно some_value , используйте != :

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

isin возвращает булевскую серию, поэтому для выбора строк, значение которых не находится в some_values , some_values серию, используя ~ :

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

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

Я считаю, что синтаксис предыдущих ответов является избыточным и трудно запоминаемым. 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')

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})
df[df['A']=='foo']

OUTPUT:
   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




dataframe