使用字典重新映射 pandas 列中的值,保留 NaN

新手上路,请多包涵

我有一本看起来像这样的字典: di = {1: "A", 2: "B"}

我想将它应用于数据框的 col1 列,类似于:

      col1   col2
0       w      a
1       1      2
2       2    NaN

要得到:

      col1   col2
0       w      a
1       A      2
2       B    NaN

我怎样才能最好地做到这一点?出于某种原因,与此相关的谷歌搜索术语只向我显示了有关如何从字典制作列的链接,反之亦然:-/

原文由 TheChymera 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 391
2 个回答

您可以使用 .replace 。例如:

 >>> df = pd.DataFrame({'col2': {0: 'a', 1: 2, 2: np.nan}, 'col1': {0: 'w', 1: 1, 2: 2}})
>>> di = {1: "A", 2: "B"}
>>> df
  col1 col2
0    w    a
1    1    2
2    2  NaN
>>> df.replace({"col1": di})
  col1 col2
0    w    a
1    A    2
2    B  NaN

或者直接在 Series ,即 df["col1"].replace(di, inplace=True)

原文由 DSM 发布,翻译遵循 CC BY-SA 4.0 许可协议

map 可以比 replace

如果您的字典有多个键,使用 mapreplace 快得多。这种方法有两个版本,具体取决于您的字典是否详尽地映射了所有可能的值(以及您是否希望不匹配项保留其值或转换为 NaN):

详尽映射

在这种情况下,表单非常简单:

 df['col1'].map(di)       # note: if the dictionary does not exhaustively map all
                         # entries then non-matched entries are changed to NaNs

尽管 map 最常用函数作为参数,但它也可以采用字典或系列: Documentation for Pandas.series.map

非详尽映射

如果您有一个非详尽的映射并希望保留不匹配的现有变量,您可以添加 fillna

 df['col1'].map(di).fillna(df['col1'])

正如@jpp 在这里的回答: Replace values in a pandas series via dictionary efficiently

基准

将以下数据与 pandas 版本 0.23.1 一起使用:

 di = {1: "A", 2: "B", 3: "C", 4: "D", 5: "E", 6: "F", 7: "G", 8: "H" }
df = pd.DataFrame({ 'col1': np.random.choice( range(1,9), 100000 ) })

并使用 %timeit 进行测试,似乎 mapreplace 快大约 10 倍。

请注意,您使用 map 的加速将因您的数据而异。最大的加速似乎是大型词典和详尽的替换。有关更广泛的基准和讨论,请参阅@jpp 答案(上面链接)。

原文由 JohnE 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题