2013-02-01 23 views
37

我是一个Python的完全新手,但它看起来像给定的字符串能够(有效)任意长度。即您可以采取string str并继续添加:str += "some stuff..."。有没有办法让这样的字符串数组?python numpy任意长度字符串数组

当我尝试这一点,每个元件仅存储单个字符

strArr = numpy.empty(10, dtype='string') 
for i in range(0,10) 
    strArr[i] = "test" 

在另一方面,我知道可以初始化一定长度的字符串数组,即

strArr = numpy.empty(10, dtype='s256') 

其可以存储最多256个字符的10个字符串

回答

68

您可以通过创建一个dtype=object的数组来完成此操作。如果你尝试长字符串分配到一个正常的numpy的阵列,它截断字符串:

>>> a = numpy.array(['apples', 'foobar', 'cowboy']) 
>>> a[2] = 'bananas' 
>>> a 
array(['apples', 'foobar', 'banana'], 
     dtype='|S6') 

但是当你使用dtype=object,你得到Python对象引用数组。所以,你可以有Python中的所有行为:

>>> a = numpy.array(['apples', 'foobar', 'cowboy'], dtype=object) 
>>> a 
array([apples, foobar, cowboy], dtype=object) 
>>> a[2] = 'bananas' 
>>> a 
array([apples, foobar, bananas], dtype=object) 

事实上,因为它是对象的数组,你可以指定任何一种蟒蛇对象的数组:

>>> a[2] = {1:2, 3:4} 
>>> a 
array([apples, foobar, {1: 2, 3: 4}], dtype=object) 

然而,这取消了使用numpy的很多好处,因为它运行在大量连续的原始内存块上,所以速度非常快。使用python对象会增加很多开销。一个简单的例子:

>>> a = numpy.array(['abba' for _ in range(10000)]) 
>>> b = numpy.array(['abba' for _ in range(10000)], dtype=object) 
>>> %timeit a.copy() 
100000 loops, best of 3: 2.51 us per loop 
>>> %timeit b.copy() 
10000 loops, best of 3: 48.4 us per loop 
+0

谢谢,你的第一个例子特别有用 - 我从来不会猜到那种行为!我并不担心这个对象的速度,所以访问速度慢应该没问题。 – DilithiumMatrix

+1

很好的答案。我已经将它与演示的链接合并到我正在研究的有关numpy数组创建的python笔记本页面中。 –

11

您可以使用对象数据类型:

>>> import numpy 
>>> s = numpy.array(['a', 'b', 'dude'], dtype='object') 
>>> s[0] += 'bcdef' 
>>> s 
array([abcdef, b, dude], dtype=object)