Python str和对象类型之间的区别
Numpy似乎区分了Python str和对象类型之间的区别,python,numpy,pandas,Python,Numpy,Pandas,Numpy似乎区分了str和object类型。例如,我可以做: >>> import pandas as pd >>> import numpy as np >>> np.dtype(str) dtype('S') >>> np.dtype(object) dtype('O') 其中,dtype('S')和dtype('O')分别对应于str和object 然而,熊猫似乎缺乏这种区别,并强迫str到object: >
str
和object
类型。例如,我可以做:
>>> import pandas as pd
>>> import numpy as np
>>> np.dtype(str)
dtype('S')
>>> np.dtype(object)
dtype('O')
其中,dtype('S')和dtype('O')分别对应于str
和object
然而,熊猫似乎缺乏这种区别,并强迫str
到object
:
>>> df = pd.DataFrame({'a': np.arange(5)})
>>> df.a.dtype
dtype('int64')
>>> df.a.astype(str).dtype
dtype('O')
>>> df.a.astype(object).dtype
dtype('O')
将类型强制为dtype('S')
也没有帮助:
>>> df.a.astype(np.dtype(str)).dtype
dtype('O')
>>> df.a.astype(np.dtype('S')).dtype
dtype('O')
对这种行为有什么解释吗 Numpy的字符串数据类型不是python字符串 因此,
pandas
故意使用本机python字符串,这需要对象数据类型
首先,让我演示一下numpy的字符串不同的含义:
In [1]: import numpy as np
In [2]: x = np.array(['Testing', 'a', 'string'], dtype='|S7')
In [3]: y = np.array(['Testing', 'a', 'string'], dtype=object)
现在,“x”是一个numpy
stringdtype(固定宽度,类似c的字符串),而y
是一个本机python字符串数组
如果我们尝试超过7个字符,我们将看到一个直接的区别。字符串数据类型版本将被截断:
In [4]: x[1] = 'a really really really long'
In [5]: x
Out[5]:
array(['Testing', 'a reall', 'string'],
dtype='|S7')
虽然对象数据类型版本可以是任意长度:
In [6]: y[1] = 'a really really really long'
In [7]: y
Out[7]: array(['Testing', 'a really really really long', 'string'], dtype=object)
其次,|S
dtype字符串不能正确保存unicode,尽管也有一个unicode固定长度字符串dtype。我暂时跳过一个例子
最后,numpy的字符串实际上是可变的,而Python字符串则不是。例如:
In [8]: z = x.view(np.uint8)
In [9]: z += 1
In [10]: x
Out[10]:
array(['Uftujoh', 'b!sfbmm', 'tusjoh\x01'],
dtype='|S7')
出于所有这些原因,
pandas
选择永远不允许类似C的固定长度字符串作为数据类型。正如您所注意到的,在pandas
中,试图将python字符串强制转换为fixed with numpy字符串是行不通的。相反,它总是使用本机python字符串,对大多数用户来说,这些字符串的行为更加直观。作为一个非常简短的解释,这并不是一个完整的答案:如果在numpy
中使用字符串数据类型,它基本上是一个固定宽度的c型字符串。在pandas
中,它们是“普通”python字符串,因此是对象类型。这可能解决了您的问题-基本上它们存储对象ndarray,而不是ndarray中的字符串。然而,我确实支持在区分类型时,它们可以更加清晰——例如,能够区分“str”和“混合”列(也报告为“O”)。事实上,pandas确实允许类似numpy的固定长度字节字符串,尽管它们很少使用,例如,pd.Series(['a','b','c'],dtype='S1'))
@mdurant Pandas将接受该语句作为有效语句,但数据类型将从“S1”更改为“O”(对象)。这以前是可能的,也许不再可能了。