将pandas数据帧中的多列列表合并为一列列表

6

我有一个包含两列列表的数据框。我想将这些列合并为单个列,并将列表合并为单个列表。此外,此列表应仅包含原始列表中的唯一值。

我尝试使用df['E']=df[['B','C']].values.tolist()将它们合并。

但是,这会创建一个由两个列表组成的列。

数据框看起来像这样:

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

最终数据框应该长成这样:
A       B       C       D       E
a1      [b1,b2] [c1,b1] d1      [b1,b2,c1]
a2      [b1,b1] [b3]    d2      [b1,b3]
a3      [b2]    [b2,b2] d3      [b2]

编辑:数据框架列表中的值是字符串。


查看 set - Paul H
@jpp 我已经对问题进行了澄清。数据框中的列表是字符串,因此提供的解决方案无法工作。我该怎么解决? - coding_monkey
3个回答

8

IIUC

df['E']=(df.B+df.C).map(set).map(list)
df
Out[81]: 
    A         B         C   D             E
0  a1  [b1, b2]  [c1, b1]  d1  [b2, b1, c1]
1  a2  [b1, b1]      [b3]  d2      [b3, b1]
2  a3      [b2]  [b2, b2]  d3          [b2]

@jpp 我已经解决了。不过你知道有没有一种方法可以显示没有空列表的数据框。我正在寻找这样的东西:df = df[df['E']!=[]]。 - coding_monkey
1
df.E = df.E.where(df.E.astype(bool), '') - BENY
你知道我怎么从数据框单元格中的列表中删除特定值吗? - coding_monkey
@Mohnish 这是另一个问题,你可以检查 list.remove。 - BENY

3
你可以在列表推导式中使用 itertools.chaindict.fromkeys。请注意,由于你选择了序列中的列表,因此你将失去所有矢量化的优势。
from itertools import chain

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

df['E'] = [list(dict.fromkeys(chain(x, y))) for x, y in zip(df['B'], df['C'])]

print(df)

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

这种方法在 Python v3.7+ 中(并且在非官方的 v3.6 版本中作为 CPython 实现细节)的好处是保留了顺序,因为字典是按照插入顺序排序的。

当然,在您的示例数据框中,列表也包含字符串。如果您的数据框不同,请发布一个新问题,准确定义您的数据框 - jpp

2
如果顺序不重要,set 就可以胜任:
import pandas as pd

data = [['a1', ['b1', 'b2'], ['c1', 'b1'], 'd1'],
        ['a2', ['b1', 'b1'], ['b3'], 'd2'],
        ['a3', ['b2'], ['b2', 'b2'], 'd3']]

df = pd.DataFrame(data=data, columns=['A', 'B', 'C', 'D'])


def uniques(xs):
    return list(set(xi for x in xs for xi in x))


df['E'] = df[['B', 'C']].apply(uniques, axis=1)

print(df)

输出

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

如果顺序很重要,使用OrderedDict
import pandas as pd
from collections import OrderedDict

data = [['a1', ['b1', 'b2'], ['c1', 'b1'], 'd1'],
        ['a2', ['b1', 'b1'], ['b3'], 'd2'],
        ['a3', ['b2'], ['b2', 'b2'], 'd3']]

df = pd.DataFrame(data=data, columns=['A', 'B', 'C', 'D'])


def uniques(xs):
    return list(OrderedDict().fromkeys(xi for x in xs for xi in x))


df['E'] = df[['B', 'C']].apply(uniques, axis=1)

输出

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接