Подтвердить что ты не робот

Как реализовать логический поиск с несколькими столбцами в пандах

У меня есть pandas df, и я хотел бы сделать что-то вроде этого (в терминах SQL):

SELECT * FROM df WHERE column1 = 'a' OR column2 = 'b' OR column3 = 'c' etc.

Теперь это работает для одной пары столбец/значение:

foo = df.loc[df['column']==value]

Однако я не уверен, как расширить это до нескольких пар столбец/значение.

  • Чтобы было понятно, каждый столбец соответствует разному значению.
4b9b3361

Ответ 1

Вам нужно заключить несколько условий в фигурные скобки из-за приоритета оператора и использовать побитовые и (&) и или (|) операторы:

foo = df.ix[(df['column1']==value) | (df['columns2'] == 'b') | (df['column3'] == 'c')]

Если вы используете and или or, то pandas, скорее всего, будет стонать, что сравнение неоднозначно. В этом случае неясно, сравниваем ли мы каждое значение в ряду в условии, и что это означает, если только 1 или все, кроме 1, соответствуют условию. Вот почему вы должны использовать побитовые операторы или numpy np.all или np.any, чтобы указать критерии соответствия.

Существует также метод запроса: http://pandas.pydata.org/pandas-docs/dev/generated/pandas.DataFrame.query.html

но есть некоторые ограничения, в основном связанные с проблемами, где может быть неоднозначность между именами столбцов и значениями индекса.

Ответ 2

Более сжатый, но не обязательно более быстрый способ заключается в использовании DataFrame.isin() и DataFrame.any()

In [27]: n = 10

In [28]: df = DataFrame(randint(4, size=(n, 2)), columns=list('ab'))

In [29]: df
Out[29]:
   a  b
0  0  0
1  1  1
2  1  1
3  2  3
4  2  3
5  0  2
6  1  2
7  3  0
8  1  1
9  2  2

[10 rows x 2 columns]

In [30]: df.isin([1, 2])
Out[30]:
       a      b
0  False  False
1   True   True
2   True   True
3   True  False
4   True  False
5  False   True
6   True   True
7  False  False
8   True   True
9   True   True

[10 rows x 2 columns]

In [31]: df.isin([1, 2]).any(1)
Out[31]:
0    False
1     True
2     True
3     True
4     True
5     True
6     True
7    False
8     True
9     True
dtype: bool

In [32]: df.loc[df.isin([1, 2]).any(1)]
Out[32]:
   a  b
1  1  1
2  1  1
3  2  3
4  2  3
5  0  2
6  1  2
8  1  1
9  2  2

[8 rows x 2 columns]

Ответ 3

Все соображения, сделанные @EdChum в 2014 году, остаются в силе, но метод pandas.Dataframe.ix устарел по сравнению с версией 0.0.20 для панд. Непосредственно из документов:

Предупреждение: Начиная с версии 0.20.0, индексатор .ix устарел, в пользу из более строгих индексаторов .iloc и .loc.

В последующих версиях pandas этот метод был заменен новыми индексными методами pandas.Dataframe.loc и pandas.Dataframe.iloc.

Если вы хотите узнать больше, в этом посте вы можете найти сравнения между методами, упомянутыми выше.

В конечном счете, на сегодняшний день (и, похоже, с этой точки зрения нет изменений в будущих версиях панд), ответ на этот вопрос следующий:

foo = df.loc[(df['column1']==value) | (df['columns2'] == 'b') | (df['column3'] == 'c')]

Ответ 4

Самый простой способ сделать это

students = [ ('jack1', 'Apples1' , 341) ,
             ('Riti1', 'Mangos1'  , 311) ,
             ('Aadi1', 'Grapes1' , 301) ,
             ('Sonia1', 'Apples1', 321) ,
             ('Lucy1', 'Mangos1'  , 331) ,
             ('Mike1', 'Apples1' , 351),
              ('Mik', 'Apples1' , np.nan)
              ]
#Create a DataFrame object
df = pd.DataFrame(students, columns = ['Name1' , 'Product1', 'Sale1']) 
print(df)


    Name1 Product1  Sale1
0   jack1  Apples1    341
1   Riti1  Mangos1    311
2   Aadi1  Grapes1    301
3  Sonia1  Apples1    321
4   Lucy1  Mangos1    331
5   Mike1  Apples1    351
6     Mik  Apples1    NaN

# Select rows in above DataFrame for which ‘Product column contains the value ‘Apples,
subset = df[df['Product1'] == 'Apples1']
print(subset)

 Name1 Product1  Sale1
0   jack1  Apples1    341
3  Sonia1  Apples1    321
5   Mike1  Apples1    351
6     Mik  Apples1    NA

# Select rows in above DataFrame for which ‘Product column contains the value ‘Apples, AND notnull value in Sale

subsetx= df[(df['Product1'] == "Apples1")  & (df['Sale1'].notnull())]
print(subsetx)
    Name1   Product1    Sale1
0   jack1   Apples1      341
3   Sonia1  Apples1      321
5   Mike1   Apples1      351

# Select rows in above DataFrame for which ‘Product column contains the value ‘Apples, AND Sale = 351

subsetx= df[(df['Product1'] == "Apples1")  & (df['Sale1'] == 351)]
print(subsetx)

   Name1 Product1  Sale1
5  Mike1  Apples1    351

# Another example
subsetData = df[df['Product1'].isin(['Mangos1', 'Grapes1']) ]
print(subsetData)

Name1 Product1  Sale1
1  Riti1  Mangos1    311
2  Aadi1  Grapes1    301
4  Lucy1  Mangos1    331

Вот оригинальная ссылка, я нашел это. Я немного редактирую https://thispointer.com/python-pandas-select-rows-in-dataframe-by-conditions-on-multiple-columns/