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

时间:2021-03-20 01:21:49

标签: python-3.x pandas dataframe filtering

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

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

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

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

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

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