我在实验numpy数组,并创建了一个numpy字符串数组:
ar1 = np.array(['avinash', 'jay'])
正如我从他们的官方指南中读到的,numpy array上的操作被传播到单个元素。所以我这样做了:
ar1 * 2
然后我得到了这个错误:
TypeError Traceback (most recent call last)
<ipython-input-22-aaac6331c572> in <module>()
----> 1 ar1 * 2
TypeError: unsupported operand type(s) for *: 'numpy.ndarray' and 'int'
但是当我使用dtype=object
ar1 = np.array(['avinash', 'jay'], dtype=object)
在创建数组时,我可以执行所有操作。
有人能告诉我为什么会这样吗?
2条答案
按热度按时间v8wbuo2f1#
NumPy数组存储为连续的内存块。它们通常具有单一的数据类型(例如整数、浮点数或定长字符串),然后将内存中的位解释为具有该数据类型的值。
使用
dtype=object
创建数组是不同的。数组占用的内存现在充满了指向Python对象的 * 指针 *,这些对象存储在内存中的 * 其他地方 *(很像Pythonlist
实际上只是指向对象的指针列表,而不是对象本身)。算术运算符(如
*
)不能处理数据类型为string_
的数组(如ar1
)(有特殊的函数代替-见下文)。NumPy只是将内存中的位视为字符,*
运算符在这里没有意义。然而,该行因为现在数组是一个(指向)Python字符串的数组。
*
运算符是为这些Python字符串对象定义的。在内存中创建新的Python字符串,并返回一个新的object
数组,其中包含对新字符串的引用。如果你有一个
string_
或unicode_
dtype的数组,并且想要重复每个字符串,你可以使用np.char.multiply
:NumPy还有很多其他的vectorised string methods。
92vpleto2#
Numpy的
str
dtype及其操作没有优化,所以在使用Numpy处理字符串时,最好还是坚持使用object
dtype。str
比object
占用更多的内存根据固定长度字符串的长度和数组的大小,该比率有所不同,但只要数组中最长的字符串长于2个字符,
str
就会消耗更多的内存(当数组中最长的字符串长度为2个字符时,它们相等)。例如,在下面的示例中,str
消耗的内存几乎是8倍。str
比object
慢Numpy的向量化字符串方法没有优化,因此在
object
数组上操作通常更快。例如,在OP中每个字符都重复的例子中,简单的*
(又名multiply()
)不仅更简洁,而且比char.multiply()
快10倍以上。即使对于那些不能很容易地应用于数组的函数,代替
str
数组的向量化char
方法,循环object
数组并处理Python字符串会更快。例如,迭代
object
数组并对每个Python字符串调用str.count()
比在str
数组上向量化的char.count()
快3倍以上。顺便说一句,如果涉及到显式循环,迭代列表比迭代numpy数组快。所以在前面的例子中,通过遍历列表可以进一步提高性能