【问题标题】:How to return difference between two column values in pandas如何返回熊猫中两列值之间的差异
【发布时间】:2021-07-23 20:46:02
【问题描述】:

我有 1 个数据框,想要检查然后返回相同数据框的两列之间的值差异,前提是第 2 列中有值。下面我的示例中的第二列是 AppliancesO,第一列是 AppliancesH

Item Name           AppliancesH          AppliancesO 
1    Joe                     TV                   TV
2   Mary           [TV; Fridge]                   TV
3   Jack  [Microwave;TV;Fridge] [Computer;TV;Fridge]
4   Pete          [Fridge;Oven]

还有 1000 多行

我正在寻找的输出是

Item Name           AppliancesH          AppliancesO                 Diff
1    Joe                     TV                   TV    
2   Mary           [TV; Fridge]                   TV               Fridge
3   Jack  [Microwave;TV;Fridge] [Computer;TV;Fridge] [Microwave;Computer]
4   Pete          [Fridge;Oven]

我知道如何比较列以确定它们是否不同,但我不知道如何返回差异

df.loc[(df['AppliancesH']!=df['AppliancesO'])& ~df.AppliancesO.isna()][['Name','AppliancesH', 'AppliancesO','Diff']]

【问题讨论】:

  • 您的代表正式吗?例如,[Microwave;TV;Fridge] 是一个字符串列表还是包含字符串的列表?
  • 是字符串列表
  • 重点是,在python中,列表分隔符是comma,而不是semi-colon。所以,[Microwave;TV;Fridge] 最多是一个只包含一个字符串的列表,即包含"Microwave;TV;Fridge"
  • 还有什么不清楚的是为什么你不处理异构类型的列。为什么有些数据只是字符串,而有些数据是字符串列表?
  • 为什么不使用只有一个组件的列表。 Special cases aren't special enough to break the rules.

标签: pandas dataframe multiple-columns


【解决方案1】:

假设以下数据

>>> dict_ = {'AppliancesH': {1: ['TV'], 2: ['TV', 'Fridge'], 3: ['Microwave', 'TV', 'Fridge'], 4: ['Fridge', 'Oven']}, 'AppliancesO': {1: ['TV'], 2: ['TV'], 3: ['Computer', 'TV', 'Fridge'], 4: []}, 'Name': {1: 'Joe', 2: 'Mary', 3: 'Jack', 4: 'Pete'}}
>>> df = pd.DataFrame(dict_)
>>> df
               AppliancesH             AppliancesO  Name
1                     [TV]                    [TV]   Joe
2             [TV, Fridge]                    [TV]  Mary
3  [Microwave, TV, Fridge]  [Computer, TV, Fridge]  Jack
4           [Fridge, Oven]                      []  Pete

您可以使用set~.symmetric_difference 来执行此类操作。让(首先定义我们需要的可调用对象:

def symdif(s: pd.Series) -> list:
    h = s.AppliancesH
    o = s.AppliancesO
    return h and o and sorted(set(h).symmetric_difference(o))

并通过pandas.DataFrame.apply使用它

>>> df['Diff'] = df.apply(axis=1, func=symdif)
>>> df
               AppliancesH             AppliancesO  Name                   Diff
1                     [TV]                    [TV]   Joe                     []
2             [TV, Fridge]                    [TV]  Mary               [Fridge]
3  [Microwave, TV, Fridge]  [Computer, TV, Fridge]  Jack  [Computer, Microwave]
4           [Fridge, Oven]                      []  Pete                     []

【讨论】:

【解决方案2】:

这是另一种方式:

df['Differences'] = (df.set_index('Name')
                     .applymap(set)
                     .apply(lambda x: set.symmetric_difference(*x),axis=1).map(list)
                     .reset_index(drop=True))

【讨论】:

    【解决方案3】:

    这也可以用异或运算符来完成

    def find_diff(row):
        if row.isna().any():
            return []
        
        diff = set(row['AppliancesH']) ^ set(row['AppliancesO'])
        return list(diff)
        
    df.apply(find_diff, axis=1)
    

    您可能还需要编写一个将这些字符串转换为列表的函数

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-04-18
      • 2015-01-16
      • 1970-01-01
      • 1970-01-01
      • 2022-10-02
      • 2017-09-07
      • 2018-12-25
      相关资源
      最近更新 更多