使用两个字典映射列

2024-04-25 04:08:56 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个df

ColA  ColB
1     1
2     3
2     2
1     2
1     3
2     1

我想使用两个不同的字典来更改ColB中的值。如果ColA中的值是1,我想使用d1,如果ColB中的值是2,我想使用d2。在

^{pr2}$

导致:

ColA  ColB
1     a
2     f
2     e
1     b
1     c
2     d

实现这一目标的最佳方式是什么?在


Tags: 目标df字典方式d2d1pr2colb
3条回答

一种方法是使用^{}map使用一个字典或另一个字典来ColB中的值,具体取决于{}的值:

import numpy as np
df['ColB'] = np.where(df.ColA.eq(1), df.ColB.map(d1), df.ColB.map(d2))

它给出了:

^{pr2}$

对于更一般的解决方案,可以使用^{},它适用于多个条件。让我们在ColA和字典中添加另一个值,以了解如何使用三种不同的映射来实现这一点:

print(df)
    ColA ColB
0     1     1
1     2     3
2     2     2
3     1     2
4     3     3
5     3     1

values_to_map = [1,2,3]
d1 = {1:'a',2:'b',3:'c'}
d2 = {1:'d',2:'e',3:'f'}
d3 = {1:'g',2:'h',3:'i'}

#create a list of boolean Series as conditions
conds = [df.ColA.eq(i) for i in values_to_map]
# List of Series to choose from depending on conds
choices = [df.ColB.map(d) for d in [d1,d2,d3]]
# use np.select to select form the choice list based on conds
df['ColB'] = np.select(conds, choices)

导致:

    ColA ColB
0     1    a
1     2    f
2     2    e
3     1    b
4     3    i
5     3    g

您可以使用一个键为tuples的新字典,并将其映射到压缩列。在

d = {**{(1, k): v for k, v in d1.items()}, **{(2, k): v for k, v in d2.items()}}
df.assign(ColB=[*map(d.get, zip(df.ColA, df.ColB))])

   ColA ColB
0     1    a
1     2    f
2     2    e
3     1    b
4     1    c
5     2    d

或者我们可以用一个lambda来绘制地图。
注意:我根据字典在列表[0, d1, d2]中的相对位置,将它们对齐以在它们之间切换。在这种情况下,什么在第一位置并不重要。我任意地放0。在

^{pr2}$

为了提高健壮性,我会远离cute并映射一个具有默认值功能的lambda

df.assign(ColB=[*map(lambda x, y: {1: d1, 2: d2}.get(x, {}).get(y), df.ColA, df.ColB)])

   ColA ColB
0     1    a
1     2    f
2     2    e
3     1    b
4     1    c
5     2    d

如果需要对多个组执行此操作,请使用dictdict来分别映射每个组。理想情况下,您可以找到一些功能性方法来创建d

d = {1: d1, 2: d2}
df['ColB'] = pd.concat([gp.ColB.map(d[idx]) for idx, gp in df.groupby('ColA')])

输出:

^{pr2}$

相关问题 更多 >