【问题标题】:Column dtype with pandas read_json带有熊猫 read_json 的列 dtype
【发布时间】:2020-05-28 09:00:03
【问题描述】:

我有一个如下所示的 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 函数设置正确的 dtype?

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    原因在this code section:

            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)转换为整数)。因此,原始(未转换的)数据将在异常块中返回。
    我猜这是熊猫中的某种错误,至少行为没有正确记录。

    另一方面,astype 的工作方式不同:它applies 'astype' 在系列上按元素),因此可以创建一个混合类型的列。

    有趣的是,当直接指定extension typepd.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
    

    【讨论】:

    • 感谢您的回答。我将等待其他答案,如果没有其他人来,我会将您的答案标记为已接受! :)
    猜你喜欢
    • 2021-10-27
    • 1970-01-01
    • 1970-01-01
    • 2017-01-13
    • 1970-01-01
    • 2013-05-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多