为什么 dtype=str 的空 DataFrame 被 "n" 填充?

Why is an empty DataFrame of dtype=str filled with "n"?

我无法理解为什么使用 dtype=str 创建的系列会产生这样的结果:

In [2]: pandas.Series(index=range(2), dtype=str)
Out[2]: 
0    NaN
1    NaN
dtype: object

但是使用 dtype=str 创建的 DataFrame 结果如下:

In [3]: pandas.DataFrame(index=range(2), columns=[0], dtype=str)
Out[3]: 
   0
0  n
1  n

为什么字符串只包含字母 "n"?

为什么 Series 和 DataFrame 之间存在这种差异?

这是在哪里记录的?!

现在是 fixed in master,从 17.0 开始应该不会成为问题。


简而言之,DataFrames 和 Series 都会创建一个空的 NumPy 数组并用 np.nan 值填充它,但是 DataFrame 使用传递的 str dtype 作为该数组的数据类型,而 Series 使用 'O' (对象) dtype.

当没有传入任何值时,类的__init__方法都会分配一个空字典作为默认数据:data = {}.

在测试对象 data 的类型后,Series 构造方法回退到生成一个 np.nan 值的数组,但使用 Numpy 的 'O' 数据类型(不是 str 数据类型)- 参见 here and then here:

np.empty(n, dtype='O') # later filled with np.nan

'O' 数据类型能够容纳任何类型的对象,因此 np.nan 不会在此处造成任何问题。

DataFrame 的 __init__ 方法也以使用 np.empty 结束,然后用 np.nan 填充空数组。区别在于使用了指定的 str 数据类型(而不是 'O' 数据类型)。代码本质上是 as follows:

v = np.empty(len(index), dtype=str)
v.fill(np.nan)

现在,当使用 str 数据类型创建时,np.empty 被转换为 '<U1' 的 NumPy dtype(即一个 unicode 字符),因此 v 变为:

array(['n', 'n'], dtype='<U1')

因为 nnan 的第一个字母(np.nan 表示为 nan)。