Python 熊猫:将多个列映射到一个列

Python 熊猫:将多个列映射到一个列,python,pandas,Python,Pandas,这是的更新版本,只处理将两列映射到新列的问题 现在我有三个列,我想使用同一个字典映射到一个新列(如果字典中没有匹配的键,则返回0) 预期产出: driver_action1 driver_action2 driver_action3 newcolumn 0 1 4 4 0 1 1 99 99 9 2

这是的更新版本,只处理将两列映射到新列的问题

现在我有三个列,我想使用同一个字典映射到一个新列(如果字典中没有匹配的键,则返回0)

预期产出:

  driver_action1 driver_action2 driver_action3  newcolumn
0              1              4              4          0
1              1             99             99          9
2             77             99             99          9
3             77             99             99          9
4              1              1              1          9
5              4              2             99          1
6              2              2             99          1
7              1             99             99          9
8             77             99             31          1
9             99             99             31          1
我不知道如何使用.applymap()或combine_first()执行此操作。

尝试以下操作:

In [174]: df['new'] = df.stack(dropna=False).map(codes).unstack() \
     ...:               .iloc[:, ::-1].ffill(axis=1) \
     ...:               .iloc[:, -1].fillna(0)
     ...:

In [175]: df
Out[175]:
  driver_action1 driver_action2 driver_action3  new
0              1              4              4  0.0
1              1             99             99  9.0
2             77             99             99  9.0
3             77             99             99  9.0
4              1              1              1  0.0
5              4              2             99  1.0
6              2              2             99  1.0
7              1             99             99  9.0
8             77             99             31  9.0
9             99             99             31  9.0
替代解决方案:

df['new'] = df.stack(dropna=False).map(codes).unstack().T \
              .apply(lambda x: x[x.first_valid_index()]
                               if x.first_valid_index() else 0)
说明:

堆栈、映射、取消堆栈映射值:

In [188]: df.stack(dropna=False).map(codes).unstack()
Out[188]:
   driver_action1  driver_action2  driver_action3
0             NaN             NaN             NaN
1             NaN             9.0             9.0
2             NaN             9.0             9.0
3             NaN             9.0             9.0
4             NaN             NaN             NaN
5             NaN             1.0             9.0
6             1.0             1.0             9.0
7             NaN             9.0             9.0
8             NaN             9.0             1.0
9             9.0             9.0             1.0
反转列顺序并沿
轴应用正向填充:

In [190]: df.stack(dropna=False).map(codes).unstack().iloc[:, ::-1].ffill(axis=1)
Out[190]:
   driver_action3  driver_action2  driver_action1
0             NaN             NaN             NaN
1             9.0             9.0             9.0
2             9.0             9.0             9.0
3             9.0             9.0             9.0
4             NaN             NaN             NaN
5             9.0             1.0             1.0
6             9.0             1.0             1.0
7             9.0             9.0             9.0
8             1.0             9.0             9.0
9             1.0             9.0             9.0
选择最后一列并用
0
填充
NaN

In [191]: df.stack(dropna=False).map(codes).unstack().iloc[:, ::-1].ffill(axis=1).iloc[:, -1].fillna(0)
Out[191]:
0    0.0
1    9.0
2    9.0
3    9.0
4    0.0
5    1.0
6    1.0
7    9.0
8    9.0
9    9.0
Name: driver_action1, dtype: float64

看起来它大部分都会起作用!我们需要更多的解释。但是我认为记录6应该有一个新的值1(b/c驱动程序动作1和驱动程序动作2都等于2)?如果任何一列有2或31,新行应该是1,即使其他列的值映射到99…也许我的请求太复杂了,我应该改为执行.loc查询?@ale19,很高兴我能帮忙:)
In [191]: df.stack(dropna=False).map(codes).unstack().iloc[:, ::-1].ffill(axis=1).iloc[:, -1].fillna(0)
Out[191]:
0    0.0
1    9.0
2    9.0
3    9.0
4    0.0
5    1.0
6    1.0
7    9.0
8    9.0
9    9.0
Name: driver_action1, dtype: float64