首页 > 解决方案 > 如何通过将条件应用于其值为元组的列来过滤数据框?

问题描述

我有一个数据框,其列值是元组。在没有重新创建数据帧的情况下,是否有一种方法可以按原样处理数据帧,以便按照以下示例过滤数据帧:

要构造数据框(请原谅复杂的构造):

import pandas as pd

columns = ['Fruit','Color','Firmness','Volume']
data = [['Apple','Green','Soft',5],
        ['Apple','Red','Firm',5],
        ['Blueberry','Blue','Soft',5],
        ['Blueberry','Blue','Soft',5],
        ['Pear','Green','Soft',5],
        ['Pear','Green','Firm',5]]

df = pd.DataFrame(data=data,columns=columns,index=[0,1,2,3,4,5])

def all_values(values):
    
    return tuple([value for value in values])

agg_dict = {'Color':all_values,'Firmness':all_values,'Volume':'sum'}

df = df.groupby(by='Fruit').agg(agg_dict)

df

            Color           Firmness        Volume
Fruit           
Apple       (Green, Red)    (Soft, Firm)    10
Blueberry   (Blue, Blue)    (Soft, Soft)    10
Pear        (Green, Green)  (Soft, Firm)    10

现在,我想要实现的是返回一个数据框,该数据框仅显示元组中第二个值为“Firm”的行。在这种情况下,这将是 Apple 行和 Pear 行。

我可以在这种情况下使用类似于 .str.contains 方法的东西吗?为了相应地过滤数据框?或者任何其他可以直接执行过滤的合适方法?

谢谢!

更新:

这是一次尝试,它至少显示了预期的结果,但没有达到目标,因为我必须将“软”指定为元组的第一部分,这不是必需的。它也感觉像一个黑客:

df = df.where(df['Firmness'] == ('Soft', 'Firm')).dropna()

df

        Color           Firmness        Volume
Fruit           
Apple   (Green, Red)    (Soft, Firm)    10.0
Pear    (Green, Green)  (Soft, Firm)    10.0

标签: python-3.xpandasdataframefiltering

解决方案


尝试agg使用 if...else

out = df.groupby('Fruit').agg(lambda x : x.sum() if x.dtype==int else tuple(x))
Out[332]: 
                    Color      Firmness  Volume
Fruit                                          
Apple        (Green, Red)  (Soft, Firm)      10
Blueberry    (Blue, Blue)  (Soft, Soft)      10
Pear       (Green, Green)  (Soft, Firm)      10

那么对于你的问题

out = out[out.Firmness.str[1]=='Firm']
out
Out[335]: 
                Color      Firmness  Volume
Fruit                                      
Apple    (Green, Red)  (Soft, Firm)      10
Pear   (Green, Green)  (Soft, Firm)      10

推荐阅读