使用Pandas应用时不一致的Nan键错误

时间:2015-10-22 17:12:04

标签: python numpy pandas

我正在重新编码数据框中的多个列,并且遇到了一个我无法理解的奇怪结果。我可能不会以最有效的方式重新编码,但它主要是我希望有人可以解释的错误。

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这令人困惑。任何帮助将不胜感激。

1 个答案:

答案 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的原始建议是更好的选择。