Pandas Dataframe:根据使用列定义的条件进行过滤

时间:2019-01-29 23:05:56

标签: python pandas dataframe filter

我不熟悉使用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的行已删除。

在火花中,我可以创建一个数据框df,然后说df.filter($'Title'.lower().contains($'Name'.lower()))

在Pandas数据框中有一种简单的表达方式吗?

4 个答案:

答案 0 :(得分:3)

熊猫中的字符串方法本质上难以向量化。我通常使用列表理解来做到这一点:

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和混合类型,可以使用列表推导来加速大多数字符串方法。参见in the spec


如果需要错误处理,请使用具有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

答案 1 :(得分:2)

使用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

答案 2 :(得分:1)

这里有另一个解决方案,但是它使用 d = (TextView) view.findViewById(R.id.description); d.setText(test[diff]); 方法,不确定速度如何保持,但这是可行的,并且很容易表达。

.apply

答案 3 :(得分:1)

还有更多选项,所有选项均基于this SO post(主要要求是使用"|".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

option 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

option 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