如何通过将条件应用于值为元组的列来过滤数据框?

How do I filter a dataframe by applying a condition to a column whose values are tuples?

我有一个数据框,其列值是元组。如果不重新创建数据框,是否有一种处理数据框的方法,以便按照以下示例过滤数据框:

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

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

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

是否有类似于 .str.contains 方法的方法可供我在此实例中使用?为了相应地过滤数据框?或者任何其他可以直接执行过滤的合适方法?

谢谢!

更新:

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

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

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

对于你的问题,使用 apply 和 lambda

df[df.apply(lambda x:x.Firmness[1]=='Firm' , axis=1)]