Pandas根据其他列的值创建新列ID,需要匹配。

4

我刚开始学编程和Pandas, 所以请别太苛刻,对我的解释也感到抱歉。

我基本上有两列数据(DM1_ID, DM2_ID),我需要根据这两列的值创建一个新的列 ('NewID')。基本上我是要为这两列创建一个新的ID。首先评估第一列中的值,并将其放入“NewID”列中。 另外,当我们执行此操作时,需要考虑DM2_ID,当该ID出现在DM1_ID中时,我需要在NewID列中给出相同的DM1_ID。

例如,在索引0中,DM1_ID为1,DM2_ID为6,我需要将1作为两个ID的新ID。当DM1_ID变为6(索引15)时,无论DM2_ID中的值是什么,我都需要将1作为NewID,因为我已经分别给了DM1_ID 1和DM1_ID 6。所以它将是1。还要注意后面可能会使用DM2_ID,而它也是1。(索引15 DM1_ID 6,DM2_ID 45,由于我已经为1和6都分配了NewID,所以我必须为DM1_ID 6分配1。对于45,我需要将其作为NewID(索引21)设为1。)

#I have a large table like this
    DM1_ID  DM2_ID
0   1       6
1   1       7
2   1       15
3   2       5
4   2       10
5   3       21
6   3       28
7   3       32
8   3       35
9   4       39
10  5       2
11  5       10
12  6       1
13  6       7
14  6       15
15  6       45
16  6       55
17  7       1
18  7       6
19  7       15
20  10      75
21  45      120
22  45      10
23  10      27
24  10      28
25  2       335

#I need to create this table

    DM1_ID  DM2_ID  abc
0   1       6        1
1   1       7        1
2   1       15       1
3   2       5        2
4   2       10       2
5   3       21       3
6   3       28       3
7   3       32       3
8   3       35       3
9   4       39       4
10  5       2        2
11  5       10       2
12  6       1        1
13  6       7        1
14  6       15       1
15  6       45       1
16  6       55       1
17  7       1        1
18  7       6        1
19  7       15       1
20  10      75       2
21  45      120      1
22  45      10       2
23  10      27       2
24  10      28       2
25  2       335      2

Any help would be appreciated. Thanks.



1
请在最终答案中展示您所期望的所有结果。解释很难理解。 - Seyi Daniel
它在我的第二个表中。我需要创建一个“abc”列,谢谢。 - rra
1
好的。我的理解是你想将 DM1_ID 复制到 abc,对吗? - Seyi Daniel
2
所以算法似乎是这样的:如果 DM1_ID 或 DM2_ID 中的值都没有被看到过,那么使用 DM1_ID 中的值作为索引。否则,使用先前用作索引的值——第一次看到任一列中的值时——作为当前行的索引。这正确吗? - G. Anderson
是的,那正是我想说的。抱歉我的解释不够清楚。你有什么想法吗? - rra
显示剩余2条评论
1个回答

2

实现您的目标的一种方法是首先持久化您的ID。然后,您可以使用这个持久化的映射表/字典,在满足条件时分配唯一的ID。我在下面包含了一个带有字典的示例,但您也可以选择使用数据库或JSON文件来持久化给定的ID:

df['pairs'] = df.apply(lambda x: [x[0], x[1]], axis=1)
pairs = df['pairs'].tolist()

u = {}
u_ = {}
for p in pairs:
    if u:
        if not u_:
            u_ = u.copy()
        else:
            u = u_.copy()
           
        for k in list(u.keys()):
            if any(x in u[k] for x in p):
                u_.update(
                    {
                        k: list(set(u[k] + p))
                    }
                )
                
            else:
                pass
            
        vals = [j for i in list(u.values()) for j in i]
        if u == u_ and not any(x in vals for x in p):
            n = max(list(u_.keys())) + 1
            u_[n] = p

        else:
            pass
            
    else:
        u[1] = p
        
u_

输出:

{1: [1, 6, 7, 45, 15, 55, 120],
 2: [75, 2, 10, 5],
 3: [32, 35, 3, 21, 28],
 4: [4, 39]}

现在让我们应用一个函数,根据我们在前一步中创建的字典为每一行分配新的ID:
f = lambda x: next(k for k,v in u_.items() if any(i in v for i in x))
df['new_ID'] = df['pairs'].apply(f)
df.drop('pairs', axis=1, inplace=True)
df

输出:

DM1_ID  DM2_ID  new_ID
0   1   6   1
1   1   7   1
2   1   15  1
3   2   5   2
4   2   10  2
5   3   21  3
6   3   28  3
7   3   32  3
8   3   35  3
9   4   39  4
10  5   2   2
11  5   10  2
12  6   1   1
13  6   7   1
14  6   15  1
15  6   45  1
16  6   55  1
17  7   1   1
18  7   6   1
19  7   15  1
20  10  75  2
21  45  120 1

22 45 10 1 23 10 27 1 24 10 28 1 25 2 335 2 - rra
我在索引22中得到了45和10。并且在索引22到23中有这些值,它们正在干扰NewID列。我的意思是23和24索引应该需要将NewID设置为2,因为在#4索引中有2和10。但它却得到了1。有没有改变代码的想法? 22. 45 10 1 23. 10 27 1 24. 10 28 1 25. 2 335 2 - rra
1
看起来您已经编辑了问题,并引入了新的数据集以及期望的输出。为了避免将来的混淆,最好保留原始问题并提交一个新问题。上述解决方案的假设是每行中的DM1_ID和DM2_ID对只能属于唯一的new_ID组。例如,如果行内对中的每个元素理论上可以属于多个new_ID组,如索引22,则您可能需要指定您的首选解决冲突的算法,例如什么是您首选的解决算法。 - nimbous

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