我正在重新编码数据框中的多个列,并且遇到了一个我无法理解的奇怪结果。我可能不会以最有效的方式重新编码,但它主要是我希望有人可以解释的错误。
s1 = pd.DataFrame([np.nan, '1', '2', '3', '4', '5'], columns=['col1'])
s2 = pd.DataFrame([np.nan, 1, 2, 3, 4, 5], columns=['col1'])
s1_dic = {np.nan: np.nan, '1': 1, '2':2, '3':3, '4':3, '5':3}
s2_dic = {np.nan: np.nan, 1: 1, 2:2, 3:3, 4:3, 5:3}
s1['col1'].apply(lambda x: s1_dic[x])
s2['col1'].apply(lambda x: s2_dic[x])
s1工作正常,但当我尝试用整数列表和np.nan做同样的事情时,我得到KeyError: nan
这令人困惑。任何帮助将不胜感激。
答案 0 :(得分:2)
解决方法是使用get dict方法,而不是lambda:
In [11]: s1['col1'].apply(s1_dic.get)
Out[11]:
0 NaN
1 1
2 2
3 3
4 3
5 3
Name: col1, dtype: float64
In [12]: s2['col1'].apply(s2_dic.get)
Out[12]:
0 NaN
1 1
2 2
3 3
4 3
5 3
Name: col1, dtype: float64
现在我不清楚为什么这是不同的......
注意:可以通过nan访问dicts:
In [21]: s1_dic[np.nan]
Out[21]: nan
In [22]: s2_dic[np.nan]
Out[22]: nan
和hash(np.nan) == 0
所以它不是......
更新:显然问题出在np.nan
vs np.float64(np.nan)
,前者有np.nan is np.nan
(因为np.nan
绑定到特定的实例化nan对象)而{{1} }}:
这意味着我们无法找到float('nan') is not float('nan')
:
float('nan')
这意味着你可以实际从dict中检索nans,任何这样的检索都是特定于实现的!事实上,由于dict使用了这些nans的id,所以上面这整个行为可能是实现特定的(如果nan共享相同的id,就像他们在REPL / ipython会话中那样)。
您可以事先捕捉到空值:
In [21]: nans = [float('nan') for _ in range(5)]
In [22]: {f: 1 for f in nans}
Out[22]: {nan: 1, nan: 1, nan: 1, nan: 1, nan: 1}
但我认为使用.get的原始建议是更好的选择。