让我们看看我能解释这是怎么回事
In [32]: ll=['one','two','three']
In [33]: a1=np.array(ll,dtype=object)
In [34]: a1
Out[34]: array(['one', 'two', 'three'], dtype=object)
In [35]: a1[1]='eleven'
In [36]: a1
Out[36]: array(['one', 'eleven', 'three'], dtype=object)
a1
就像ll
由指针 - 指向驻留在内存中其他位置的字符串的指针。我可以改变任何这些指针,就像我可以在列表中一样。在大多数方面a1
的行为就像一个列表 - 除了它可以重塑,并做一些其他基本的事情。
In [37]: a1.reshape(3,1)
Out[37]:
array([['one'],
['eleven'],
['three']], dtype=object)
但是,如果我做一个string
阵列
In [38]: a2=np.array(ll)
In [39]: a2
Out[39]:
array(['one', 'two', 'three'],
dtype='<U5')
In [42]: a1.itemsize
Out[42]: 4
In [43]: a2.itemsize
Out[43]: 20
的值存储在阵列的数据缓冲。这里它创建了一个数组,每个元素有5个Unicode字符(Python3)(每个字符5 * 4字节)。
现在,如果我取代的a2
的元素,我可以得到截断
In [44]: a2[1]='eleven'
In [45]: a2
Out[45]:
array(['one', 'eleve', 'three'],
dtype='<U5')
,因为只有5个新值超出所分配的空间的字符。
所以有一个折衷 - 访问速度更快,因为字节存储在固定的已知大小的数组中,但不能存储更大的东西。
你可以每个元素分配更多的空间:
In [46]: a3=np.array(ll,dtype='|U10')
In [47]: a3
Out[47]:
array(['one', 'two', 'three'],
dtype='<U10')
In [48]: a3[1]='eleven'
In [49]: a3
Out[49]:
array(['one', 'eleven', 'three'],
dtype='<U10')
genfromtxt
是一个用于创建与字符串数组dtypes的常用工具。在设置字符串长度之前(至少在使用dtype=None
时),它会等待它读取所有文件。字符串字段通常是多字段结构化数组的一部分。字符串字段通常是标签或ID,而不是您经常更改的内容。
我可以想象写一个函数,可以检查字符串长度对dtype和提出一个错误,如果截断会发生。但是这会减缓行动。
def foo(A, i, astr):
if A.itemsize/4<len(astr):
raise ValueError('too long str')
A[i] = astr
In [69]: foo(a2,1,'four')
In [70]: a2
Out[70]:
array(['one', 'four', 'three'],
dtype='<U5')
In [72]: foo(a2,1,'eleven')
...
ValueError: too long str
但它值得额外的工作?
*” ......在截断的情况下,产生异常?“*如果设置某个标志启用了这种行为,这可能会很好,可能类似于'numpy.seterr()'控制浮点错误的处理方式。我从来没有见过这样的旗帜,但作为一个增强的numpy请求,我会给它一个+1。 –
@WarrenWeckesser。我同意,它也可能是一个警告或类似的东西。 –