如何用列表分解熊猫数据框以用相同的ID标记同一行中的那些?

Posted

技术标签:

【中文标题】如何用列表分解熊猫数据框以用相同的ID标记同一行中的那些?【英文标题】:How to explode pandas dataframe with lists to label the ones in the same row with same id? 【发布时间】:2022-01-22 00:44:43 【问题描述】:

例如,我有一个这样的熊猫数据框:

忽略“名称”列,我想要一个看起来像这样的数据框,用它们的“ID”标记同一组的哈希

这里,我们遍历每一行,遇到“8a43”,给它分配ID 1,找到相同hash值的地方,我们给ID分配1。然后我们继续下一行,遇到79e2和 b183。然后我们遍历所有行,在任何找到这些值的地方,我们将它们的 ID 存储为 2。现在当我们到达“abc7”时就会出现问题。它将被分配 ID=5,因为它之前在“abc5”中遇到过。但我也希望在当前行之后的行中,无论我在哪里找到“26ea”,都将 ID=5 分配给那些。

我希望这一切都有意义。如果没有,请随时通过 cmets 或消息与我联系。我会尽快清除的。

【问题讨论】:

不应该 abc4 有 ID 2 吗? @Julkar9 是的,是的。编辑帖子以包含正确的图像 还有5 应该是4 in ID 两个之前看到的hash值(对应不同的ID)能否一起出现,比如[1cee(5), b183(2)]? 【参考方案1】:

使用networkx solution作为常用值的字典,在str中选择Hash_Value中的第一个值并使用Series.map

#if necessary convert to lists
#df['Hash_Value'] = df['Hash_Value'].str.strip('[]').str.split(', ')

import networkx as nx

G=nx.Graph()
for l in df['Hash_Value']:
    nx.add_path(G, l)

new = list(nx.connected_components(G))

print (new)
['8a43', '79e2', 'b183', 'f82a', '5ea9', '1cee', '26ea', 'eaa7']

mapped =  node: cid for cid, component in enumerate(new) for node in component

df['ID'] = df['Hash_Value'].str[0].map(mapped) + 1

print (df)
           Hash_Value   Name  ID
0              [8a43]   abcl   1
1        [79e2, b183]   abc2   2
2              [f82a]   abc3   3
3              [b183]   abc4   2
4  [eaa7, 5ea9, 1cee]   abc5   4
5              [5ea9]   abc6   4
6        [1cee, 26ea]   abc7   4
7              [79e2]   abc8   2
8              [8a43]   abc9   1
9              [26ea]  abc10   4

【讨论】:

【参考方案2】:

使用dict的解决方案

import numpy as np
import pandas as pd

hashvalues = list(df['Hash_Value'])

dic, i = , 1
id_list = []
for hashlist in hashvalues:
    # convert to list
    if isinstance(hashlist, str):
        hashlist = hashlist.replace('[','').replace(']', '')
        hashlist = hashlist.split(',')

        # check if the hash is unknown
        if hashlist[0] not in dic:
            # Assign a new id
            dic[hashlist[0]] = i
            k = i
            i += 1
        else:
            # if known use existing id
            k = dic[hashlist[0]]
            
        for h in hashlist[1:]:
            # set id of the rest of the list hashes
            # equal to the first hashes's id
            dic[h] = k
            
        id_list.append(k)
    else:
        id_list.append(np.nan)
    
     print(df)

               Hash   Name  ID
0            [8a43]   abc1   1
1       [79e2,b183]   abc2   2
2            [f82a]   abc3   3
3            [b183]   abc4   2
4  [eaa7,5ea9,1cee]   abc5   4
5            [5ea9]   abc6   4
6       [1cee,26ea]   abc7   4
7            [79e2]   abc8   2
8            [8a43]   abc9   1
9            [26ea]  abc10   4

【讨论】:

如何处理其中的空值?我在第 7 行收到错误“'NoneType' object has no attribute 'replace'”这样数据框的顺序就不会乱了 @ChintanMehta 如果哈希值为空,对应的 ID 是什么? 我解决了,谢谢!我添加了一个 if-else 语句,当 Hash 值为 null 时,将 null 附加到 id_list 以及

以上是关于如何用列表分解熊猫数据框以用相同的ID标记同一行中的那些?的主要内容,如果未能解决你的问题,请参考以下文章

切片熊猫数据框以获取不连续的列

如何用熊猫(python)中的其他值替换NAN [重复]

如何用jquery将勾中复选框的那一行的数据自动添加到同页面的另一个表格

python如何用print打印出列表

如何用sql语句将多行合并成一行

熊猫如何为每个新行爆炸几个列表项