Pandas Dataframe: фильтрация по условию, определенному с использованием столбцов - PullRequest
0 голосов
/ 30 января 2019

Я новичок в использовании Pandas фреймов данных, но очень часто использовал фреймы данных Spark.Рассмотрим следующий фрейм данных.

Name   Value   Title
mickey 20      wonderland
donald 10      welcome to donald's castle
minnie 86      Minnie mouse clubhouse

Я хочу сохранить только те строки, в которых «Имя» содержится в регистре игнорирования «Заголовок».Таким образом, в этом случае отфильтрованный фрейм данных должен выглядеть следующим образом:

Name   Value   Title
donald 10      welcome to donald's castle
minnie 86      Minnie mouse clubhouse

Строка с Name = mickey была отброшена.

В Spark я могу создать фрейм данных df и затем сказатьdf.filter($'Title'.lower().contains($'Name'.lower()))

Есть ли простой способ выразить это в кадрах данных Pandas?

Ответы [ 4 ]

0 голосов
/ 30 января 2019

Вот еще несколько опций, основанных на этой публикации SO (основное требование - "|".join(...))

Опция 1 - df.query()

df_match = df.query("Title.str.lower().str.contains('|'.join(Name.str.lower()))")
print(df_match)
     Name  Value                       Title
1  donald     10  welcome to donald's castle
2  minnie     86      Minnie mouse clubhouse

опция 2

print(df[df['Title'].str.lower().str.contains('|'.join(df['Name'].str.lower()))])
     Name  Value                       Title
1  donald     10  welcome to donald's castle
2  minnie     86      Minnie mouse clubhouse

опция 3 - с использованием NumPy where

from numpy import where
df['match'] = (
                where(df.Title.str.lower().str.contains(
                    '|'.join(df['Name'].str.lower()))
                , True, False)
                )
print(df[df['match']==True])
     Name  Value                       Title  match
1  donald     10  welcome to donald's castle   True
2  minnie     86      Minnie mouse clubhouse   True
0 голосов
/ 30 января 2019

Использование numpy.core.chararray

s1=df.Title.str.upper().values.astype(str)
s2=df.Name.str.upper().values.astype(str)
df[np.core.chararray.find(s1,s2)!=-1]
Out[790]: 
     Name  Value                       Title
1  donald     10  welcome to donald's castle
2  minnie     86      Minnie mouse clubhouse
0 голосов
/ 30 января 2019

Вот еще одно решение, но в нем используется метод .apply, не совсем понятно, как он справляется с точки зрения скорости, но это работает и его довольно выразительно.

df[df.apply(lambda x: x.Name.upper() in x.Title.upper(), axis=1) == True]


# Output
    Name    Value Title
1   donald  10    welcome to donald's castle
2   minnie  86    Minnie mouse clubhouse
0 голосов
/ 30 января 2019

Строковые методы в пандах по своей сути трудно векторизовать.Я обычно делаю это, используя списочное понимание:

df[[y.lower() in x.lower() for x, y in zip(df['Title'], df['Name'])]]

     Name  Value                       Title
1  donald     10  welcome to donald's castle
2  minnie     86      Minnie mouse clubhouse

Большинство строковых методов могут быть ускорены с использованием списочных пониманий, если вы не беспокоитесь о NaN и смешанных типах.См. Для циклов с пандами - Когда мне это нужно? .


Если вам нужна обработка ошибок, используйте функцию с try-except обработкой.Это все еще быстрее.

def try_check(x, y):
    try:
        return y.lower() in x.lower()
    except AttributeError: 
        return False

df[[try_check(x, y) for x, y in zip(df['Title'], df['Name'])]]

     Name  Value                       Title
1  donald     10  welcome to donald's castle
2  minnie     86      Minnie mouse clubhouse
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...