Pandas:组合列不重复/组合后找到唯一的词

Pandas: combine columns without duplicates/ find unique words after combining

我有一个数据框,我想在其中连接某些列。

我的问题是这些列中的文本可能包含也可能不包含重复信息。我想去掉重复项以便只保留相关信息。

例如,如果我有一个数据框,例如:

pd.read_csv("animal.csv")

  animal1         animal2        label  
1 cat dog         dolphin        19
2 dog cat         cat            72
3 pilchard 26     koala          26
4 newt bat 81     bat            81

我想合并列,但只保留每个字符串的唯一信息。

您可以看到在第 2 行中,'cat' 包含在 'Animal1' 和 'Animal2' 两列中。在第 3 行中,数字 26 在 'Animal1' 和 'Label' 列中。而在第 4 行中,'Animal2' 和 'Label' 列中的信息已按顺序包含在 'Animal1'.

我通过执行以下操作合并列

animals["detail"] = animals["animal1"].map(str) + animals["animal2"].map(str) + animals["label"].map(str)

  animal1         animal2        label        detail  
1 cat dog         dolphin        19           cat dog dolphin 19
2 dog cat         cat            72           dog cat cat 72
3 pilchard 26     koala          26           pilchard 26 koala 26
4 newt bat 81     bat            81           newt bat 81 bat 81

第 1 行没问题,但其他行当然包含如上所述的重复项。

我想要的输出是:

  animal1         animal2        label        detail  
1 cat dog         dolphin        19           cat dog dolphin 19
2 dog cat         cat            72           dog cat 72
3 pilchard 26     koala          26           pilchard koala 26
4 newt bat 81     bat            81           newt bat 81

或者如果我只能保留详细信息列中每行每个单词/数字的第一个唯一实例,这也适用,即:

  detail 
1 cat dog dolphin 19
2 dog cat 72
3 pilchard koala 26
4 newt bat 81

我看过对 python 中的字符串执行此操作,例如How can I remove duplicate words in a string with Python?, , 但无法弄清楚如何将其应用于详细信息列中的各个行。我已经考虑过在合并列之后拆分文本,然后使用 apply 和 lambda,但还没有让它起作用。或者在合并列时是否有办法做到这一点?

我有 但想在 python 中重新编码。

非常感谢任何帮助或建议。我目前正在使用 Spyder(Python 3.5)

您可以添加自定义函数,首先按空格分隔,然后按 pandas.unique 获取唯一值,最后加入字符串:

animals["detail"] = animals["animal1"].map(str) + ' ' + 
                    animals["animal2"].map(str) + ' ' +
                    animals["label"].map(str)

animals["detail"] = animals["detail"].apply(lambda x: ' '.join(pd.unique(x.split())))
print (animals)
       animal1  animal2  label              detail
1      cat dog  dolphin     19  cat dog dolphin 19
2      dog cat      cat     72          dog cat 72
3  pilchard 26    koala     26   pilchard 26 koala
4  newt bat 81      bat     81         newt bat 81

也可以在 apply 中加入值:

animals["detail"] = animals.astype(str)
                           .apply(lambda x: ' '.join(pd.unique(' '.join(x).split())),axis=1)
print (animals)
       animal1  animal2  label              detail
1      cat dog  dolphin     19  cat dog dolphin 19
2      dog cat      cat     72          dog cat 72
3  pilchard 26    koala     26   pilchard 26 koala
4  newt bat 81      bat     81         newt bat 81

set 的解决方案,但它改变了顺序:

animals["detail"] = animals.astype(str)
                           .apply(lambda x: ' '.join(set(' '.join(x).split())), axis=1)
print (animals)
       animal1  animal2  label              detail
1      cat dog  dolphin     19  cat dolphin 19 dog
2      dog cat      cat     72          cat dog 72
3  pilchard 26    koala     26   26 pilchard koala
4  newt bat 81      bat     81         bat 81 newt

我建议在过程结束时使用 python set.

删除重复项

这是一个示例函数:

def dedup(value):
    words = set(value.split(' '))
    return ' '.join(words)

它是这样工作的:

val = 'dog cat cat 81'
print dedup(val)

81 dog cat

如果您想订购详细信息,可以使用 collectionspd.unique 中的 oredereddict 而不是 set.

然后 apply 它(类似于 map)在您的详细信息列中以获得所需的结果:

animals.detail = animals.detail.apply(dedup)

如果想保持单词出现的顺序,可以先将每列的单词拆分,合并,去掉重复的,最后拼接成新的一列。

df['detail'] = df.astype(str).T.apply(lambda x: x.str.split())
                 .apply(lambda x: ' '.join(pd.Series(sum(x,[])).drop_duplicates()))

df
Out[46]: 
         animal1   animal2   label                 detail
0      1 cat dog   dolphin       19  1 cat dog dolphin 19
1      2 dog cat       cat       72          2 dog cat 72
2  3 pilchard 26     koala       26   3 pilchard 26 koala
3  4 newt bat 81       bat       81         4 newt bat 81