比较数据框各列中的嵌套列表值

时间:2018-12-20 22:18:22

标签: python pandas

如何比较数据框两列中的列表,并确定一个列表中的元素是否在另一列表中,并使用缺少的元素创建另一列。

数据框看起来像这样:

df = pd.DataFrame({'A': ['a1', 'a2', 'a3'],
               'B': [['b1', 'b2'], ['b1', 'b2', 'b3'], ['b2']],
               'C': [['c1', 'b1'], ['b3'], ['b2', 'b1']],
               'D': ['d1', 'd2', 'd3']})

我想比较C列的元素是否在B列中,并将缺少的值输出到E列,所需的输出是:

df = pd.DataFrame({'A': ['a1', 'a2', 'a3'],
               'B': [['b1', 'b2'], ['b1', 'b2', 'b3'], ['b2']],
               'C': [['c1', 'b1'], ['b3'], ['b2', 'b1']],
               'D': ['d1', 'd2', 'd3']
               'E': ['b2', ['b1','b2'],'']})

4 个答案:

答案 0 :(得分:4)

就像您的previous related question一样,您可以使用列表推导。通常,您不应该强制执行多种不同类型的输出,例如liststr,取决于结果。因此,我在此解决方案中始终选择了列表。

df['E'] = [list(set(x) - set(y)) for x, y in zip(df['B'], df['C'])]

print(df)

    A             B         C   D         E
0  a1      [b1, b2]  [c1, b1]  d1      [b2]
1  a2  [b1, b2, b3]      [b3]  d2  [b1, b2]
2  a3          [b2]  [b2, b1]  d3        []

答案 1 :(得分:2)

def Desintersection(i):

    Output = [b for b in df['B'][i] if b not in df['C'][i]]

    if(len(Output) == 0):

        return ''

    elif(len(Output) == 1):

        return Output[0]

    else:

        return Output



df['E'] = df.index.map(Desintersection)


df

enter image description here

答案 2 :(得分:1)

就像我对以前的回答所做的一样

(df.B.map(set)-df.C.map(set)).map(list)
Out[112]: 
0        [b2]
1    [b2, b1]
2          []
dtype: object

答案 3 :(得分:0)

我同意@jpp,您不应过多地混合类型,因为当您尝试将相同的函数应用于新的E列时,它将失败,并导致期望每个元素都是一个列表。

这将适用于E,因为它会在比较之前将单个str值转换为[str]。

import pandas as pd

df = pd.DataFrame({'A': ['a1', 'a2', 'a3'],
                   'B': [['b1', 'b2'], ['b1', 'b2', 'b3'], ['b2']],
                   'C': [['c1', 'b1'], ['b3'], ['b2', 'b1']],
                   'D': ['d1', 'd2', 'd3']})


def difference(df, A, B):
    elements_to_list = lambda x: [n if isinstance(n, list) else [n] for n in x]
    diff = [list(set(a).difference(set(b))) for a, b in zip(elements_to_list(df[A]), elements_to_list(df[B]))]
    diff = [d if d else "" for d in diff]  # replace empty lists with empty strings
    return [d if len(d) != 1 else d[0] for d in diff]  # return with single values extracted from the list


df['E'] = difference(df, "B", "C")
df['F'] = difference(df, "B", "E")
print(list(df['E']))
print(list(df['F']))

['b2', ['b2', 'b1'], '']
['b1', 'b3', 'b2']