Python Pandas的read_csv,dtype=pd。CategoricalDtype()创建“对象”类别,即使输入数据是数字

Python Pandas的read_csv,dtype=pd。CategoricalDtype()创建“对象”类别,即使输入数据是数字,python,pandas,Python,Pandas,我正在尝试使用pandas的read_csv,并将dtype参数设置为CategoricalDtype。它确实像预期的那样生成带有类别的数据帧,但我注意到类别本身是对象类型,而不是某种int import pandas as pd from io import StringIO data = 'data\n1\n2\n3\n' df = pd.read_csv(StringIO(data), dtype=pd.CategoricalDtype()) df['data'] 导致 0 1

我正在尝试使用pandas的read_csv,并将dtype参数设置为CategoricalDtype。它确实像预期的那样生成带有类别的数据帧,但我注意到类别本身是对象类型,而不是某种int

import pandas as pd
from io import StringIO

data = 'data\n1\n2\n3\n'
df = pd.read_csv(StringIO(data), dtype=pd.CategoricalDtype())
df['data']
导致

0    1
1    2
2    3
Name: data, dtype: category
Categories (3, object): ['1', '2', '3']
0    1
1    2
2    3
dtype: category
Categories (3, int64): [1, 2, 3]
这有点令人惊讶,因为如果我创建一个数字列表,然后生成一个系列,而不使用read_csv,则类别是int64

导致

0    1
1    2
2    3
Name: data, dtype: category
Categories (3, object): ['1', '2', '3']
0    1
1    2
2    3
dtype: category
Categories (3, int64): [1, 2, 3]

我知道我可以显式地将类别传递给CategoricalDtype以避免这种情况,但这有点烦人。这是预期的行为吗?

是的,这是预期的行为。当读取csv时,所有数据都存储为字符串,pandas基本上可以在解析数据后智能地猜测列是否应该是其他内容,除非事先给定了数据类型。这可能过于简化了熊猫如何解释基于文本的文件,所以如果我错了或有更多信息要包含,请有人纠正我

如果删除pd.read_csv中的手动数据类型,pandas将读取您的数据,然后准确猜测该列应为int数据类型。通过手动设置dtype=pd.CATEGRICALDTYPE注意,您还可以使用dtype=category获得结果。在将int dtype转换为CATEGRICALDTYPE之前,您将跳过对int dtype的隐式转换,这就是类别具有对象dtype的原因

在第二个示例中,列表lst中的数据都是数字。由于没有显式提供类别,pandas将利用lst中的唯一值来创建其类别。由于类别中的所有值均为int,因此lst中的唯一值将为dtype int。如果您希望第二个示例中的类别为字符串,则需要重新编码lst以包含字符串,例如lst=[strx for x in lst],或者更好,创建系列后,可以使用具有对象/字符串数据类型的副本替换基础类别


谢谢我明白你的意思。我只是觉得这种行为有点令人沮丧,因为如果我想查询数据帧,我必须把数字放在引号里。在我意识到这一点之前,它实际上欺骗了我一段时间。将列强制转换为int类型可能是一个更好的主意,但是当我处理一个大数据集时,验证最佳类型以优化内存使用会变得单调乏味。是的,如果您已经在处理数值数据,那么使用pd.CategoricalDtype真的没有任何好处。它主要适用于包含大量重复值的字符串的列。