使用两个字典的Map列

OD1*_*995 11 python pandas

我有一个df

ColA  ColB
1     1
2     3
2     2
1     2
1     3
2     1
Run Code Online (Sandbox Code Playgroud)

我想使用两个不同的字典来更改ColB中的值。我想使用d1ColA中的值为1以及d2ColB中的值为2的情况。

d1 = {1:'a',2:'b',3:'c'}
d2 = {1:'d',2:'e',3:'f'}
Run Code Online (Sandbox Code Playgroud)

导致:

ColA  ColB
1     a
2     f
2     e
1     b
1     c
2     d
Run Code Online (Sandbox Code Playgroud)

实现此目标的最佳方法是什么?

yat*_*atu 11

一种方法是使用np.wheremap中的值ColB使用一个词典或其他取决于的值ColA

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

这使:

    ColA ColB
0     1    a
1     2    f
2     2    e
3     1    b
4     1    c
5     2    d
Run Code Online (Sandbox Code Playgroud)

对于更通用的解决方案,可以使用np.select适用于多种条件的。让我们在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)
Run Code Online (Sandbox Code Playgroud)

导致:

    ColA ColB
0     1    a
1     2    f
2     2    e
3     1    b
4     3    i
5     3    g
Run Code Online (Sandbox Code Playgroud)


piR*_*red 7

您可以使用键为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
Run Code Online (Sandbox Code Playgroud)

或者,我们可以通过lambda来可爱。
注意:我将字典对齐以根据它们在列表中的相对位置进行切换[0, d1, d2]。在这种情况下,第一位置是什么都没关系。我0随便放。

df.assign(ColB=[*map(lambda x, y: [0, d1, d2][x][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
Run Code Online (Sandbox Code Playgroud)

为了健壮起见,我会尽量避免可爱,并映射具有默认值功能的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
Run Code Online (Sandbox Code Playgroud)

  • 一旦有两个以上的命令,就被低估了!+1 (2认同)