DataFrame中的字符串,但dtype是对象

时间:2014-01-09 11:16:23

标签: python pandas numpy types series

为什么Pandas告诉我我有对象,尽管所选列中的每个项目都是字符串 - 即使在显式转换后也是如此。

这是我的DataFrame:

<class 'pandas.core.frame.DataFrame'>
Int64Index: 56992 entries, 0 to 56991
Data columns (total 7 columns):
id            56992  non-null values
attr1         56992  non-null values
attr2         56992  non-null values
attr3         56992  non-null values
attr4         56992  non-null values
attr5         56992  non-null values
attr6         56992  non-null values
dtypes: int64(2), object(5)

其中五个是dtype object。我明确地将这些对象转换为字符串:

for c in df.columns:
    if df[c].dtype == object:
        print "convert ", df[c].name, " to string"
        df[c] = df[c].astype(str)

然后,df["attr2"]仍有dtype object,但type(df["attr2"].ix[0]显示str,这是正确的。

Pandas区分int64float64以及object。当没有dtype str时,它背后的逻辑是什么?为什么str覆盖了object

4 个答案:

答案 0 :(得分:125)

dtype对象来自NumPy,它描述了ndarray中元素的类型。 ndarray中的每个元素必须具有相同的字节大小。对于int64和float64,它们是8个字节。但对于字符串,字符串的长度不固定。因此,Pandas不是直接在ndarray中保存字符串的字节,而是使用对象ndarray,它保存指向对象的指针,因此这种类型的ddarray是对象。

以下是一个例子:

  • int64数组包含4个int64值。
  • 对象数组包含4个指向3个字符串对象的指针。

enter image description here

答案 1 :(得分:10)

@HYRY的答案很好。我只想提供更多背景信息。

阵列将数据存储为连续固定大小存储块。这些属性的组合使阵列可以快速进行数据访问。例如,考虑您的计算机如何存储32位整数[3,0,1]

enter image description here

如果您要求计算机获取数组中的第3个元素,它将从头开始,然后跨64位跳转到第3个元素。 确切知道要跳过多少位才使数组快速运行

现在考虑字符串['hello', 'i', 'am', 'a', 'banana']的顺序。字符串是大小不同的对象,因此,如果您尝试将它们存储在连续的内存块中,它将最终看起来像这样。

enter image description here

现在,您的计算机没有快速的方法来访问随机请求的元素。克服这个问题的关键是使用指针。基本上,将每个字符串存储在某个随机的内存位置,然后用每个字符串的内存地址填充数组。 (内存地址只是整数。)所以现在,事情看起来像这样

enter image description here

现在,如果您像以前一样要求计算机获取第三个元素,它可以跨64位跳转(假设内存地址是32位整数),然后再执行一个步骤来获取字符串。 / p>

NumPy面临的挑战是不能保证指针实际上指向字符串。这就是为什么它将dtype报告为“对象”的原因。

要毫不客气地插上我自己讨论的course on NumPy

答案 2 :(得分:3)

从1.0.0版开始(2020年1月),pandas作为一项实验功能被引入,它通过pandas.StringDtype为字符串类型提供了一流的支持。

默认情况下您仍然会看到.gitignore,但可以通过指定object中的dtype或简单地使用pd.StringDtype来使用新类型:

'string'

答案 3 :(得分:2)

可接受的答案是好的。只是想提供一个referenced the documentation的答案。该文档说:

  

Pandas使用对象dtype来存储字符串。

正如主要评论所说:“不用担心;它应该是这样的。” (尽管公认的答案在解释“为什么”方面做得很好,字符串是可变长度的)

  

但是对于字符串,字符串的长度不是固定的。