【发布时间】:2021-08-24 19:44:27
【问题描述】:
我正在尝试将以下数据框中的 values 列的元素用作字典中的键。
In [1]: import numpy as np
...: import pandas as pd
...: rng = pd.date_range('2021-06-01', periods=4)
...: values = [1, -1, 0, np.nan]
...: df = pd.DataFrame(values, index=rng, columns=['values'])
In [2]: df
Out[2]:
values
2021-06-01 1.0
2021-06-02 -1.0
2021-06-03 0.0
2021-06-04 NaN
目标是将values 列的元素映射到单独列中的一组新值,以生成以下数据框:
values new_values
2021-06-01 1.0 A
2021-06-02 -1.0 B
2021-06-03 0.0 C
2021-06-04 NaN D
所以我创建了一个字典,其中的键作为 values 列中的元素。
In [3]: repl = {1: 'A', 0: 'B', -1: 'C',np.nan: 'D'}
In [4]: df['rule'] = df['Val'].apply(lambda x: repl[x])
然而,'NaN' 正在创建一个关键错误(尽管它是可散列的)。
KeyError Traceback (most recent call last)
<ipython-input-143-2e9d3caa7f9c> in <module>
----> 1 df['rule'] = df['Val'].apply(lambda x: repl[x])
~/opt/miniconda3/envs/PyAlgo/lib/python3.7/site-packages/pandas/core/series.py in apply(self, func, convert_dtype, args, **kwds)
4136 else:
4137 values = self.astype(object)._values
-> 4138 mapped = lib.map_infer(values, f, convert=convert_dtype)
4139
4140 if len(mapped) and isinstance(mapped[0], Series):
pandas/_libs/lib.pyx in pandas._libs.lib.map_infer()
<ipython-input-143-2e9d3caa7f9c> in <lambda>(x)
----> 1 df['rule'] = df['Val'].apply(lambda x: repl[x])
KeyError: nan
显然,我可以为这个简单的示例手动创建列。然而,这只是一个最低限度可重现的例子。实际上,我有一个更大的数据框,其中包含更多潜在的键。
两个问题:
- 为什么“NaN”尽管是可散列的,但仍会生成密钥错误?
- 解决此问题的最佳方法是什么?一种可能性是在原始数据框中将“NaN”值设置为另一个值,例如 -999?
【问题讨论】:
-
np.nan当然可以用作字典键。你可以自己尝试来证明这一点。抱怨不是np.nan不可散列,而是密钥不存在。有没有可能你真的得到了字符串“nan”? Pandas 做了很多自动转换。 -
np.nan 确实是可散列的,如下所示。
-
在 [1]: 将 numpy 作为 np 导入 [2]: hash(np.nan) Out[2]: 0 在 [3]: d = {-1: 'A', np .nan: 'B'} 输入 [4]: d[np.nan] 输出[4]: 'B'
标签: python pandas hashtable nan