使用pandas read_json的dtype列。

问题描述 投票:1回答:1

我有一个json文件,看起来像这样。

[{"A": 0, "B": "x"}, {"A": 1, "B": "y", "C": 0}, {"A": 2, "B": "z", "C": 1}]

由于 "C "列包含一个NaN值(第一行),pandas自动推断它的dtype是 "float64"。

>>> pd.read_json(path).C.dtype
dtype('float64')

然而,我希望 "C "列的dtype是 "Int32"。pd.read_json(path, dtype={"C": "Int32"}) 不见得。

>>> pd.read_json(path, dtype={"C": "Int32"}).C.dtype
dtype('float64')

取而代之的是: pd.read_json(path).astype({"C": "Int32"}) 确实有效。

>>> pd.read_json(path).astype({"C": "Int32"}).C.dtype
Int32Dtype()

为什么会这样?我怎样才能通过只使用 pd.read_json 函数?

python pandas
1个回答
1
投票

原因就在 本法条:

        dtype = (
            self.dtype.get(name) if isinstance(self.dtype, dict) else self.dtype
        )
        if dtype is not None:
            try:
                dtype = np.dtype(dtype)
                return data.astype(dtype), True
            except (TypeError, ValueError):
                return data, False

它可以转换 'Int32'numpy.int32 然后,当试图将整个列(数组)转换为这种类型时,会导致一个值错误(不能将非无限值(NA或inf)转换为整数)。由于这个原因,原始(未转换的)数据在异常块中被返回。我想这是pandas中的某个bug,至少这个行为没有被正确记录下来。

astype而另一方面,pandas的工作方式不同:它的工作方式是 适用 'astype' 元素上),因此可以创建一个混合类型的列。

有趣的是,当指定了 扩展型 pd.Int32Dtype() 直接(而不是它的字符串别名 'Int32'),乍一看你会得到想要的结果,但如果你再看一下类型,它们仍然是浮动的。

df = pd.read_json(json, dtype={"C": pd.Int32Dtype})
print(df)
#   A  B    C
#0  0  x  NaN
#1  1  y    0
#2  2  z    1
print(df.C.map(type))
#0    <class 'float'>
#1    <class 'float'>
#2    <class 'float'>
#Name: C, dtype: object

相比之下:

print(df.C.astype('Int32').map(type))
#0    <class 'pandas._libs.missing.NAType'>
#1                            <class 'int'>
#2                            <class 'int'>
#Name: C, dtype: object
© www.soinside.com 2019 - 2024. All rights reserved.