【问题标题】:How to explode pandas dataframe with lists to label the ones in the same row with same id?如何用列表分解熊猫数据框以用相同的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)]?

标签: python pandas hashmap logic pandas-explode


【解决方案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 以及
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-18
    相关资源
    最近更新 更多