18

是否可以在事先不知道字符串长度的情况下初始化一个包含字符串的 numpy recarray?

作为一个(人为的)例子:

mydf = np.empty( (numrows,), dtype=[ ('file_name','STRING'), ('file_size_MB',float) ] )

问题是我在用信息填充它之前构建了我的recarray,而且我不一定知道file_name提前的最大长度。

我所有的尝试都导致字符串字段被截断:

>>> mydf = np.empty( (2,), dtype=[('file_name',str),('file_size_mb',float)] )
>>> mydf['file_name'][0]='foobarasdf.tif'
>>> mydf['file_name'][1]='arghtidlsarbda.jpg'
>>> mydf
array([('', 6.9164002347457e-310), ('', 9.9413127e-317)], 
      dtype=[('file_name', 'S'), ('file_size_mb', '<f8')])
>>> mydf['file_name']
array(['f', 'a'], 
      dtype='|S1')

(顺便说一句,为什么mydf['file_name']显示'f'和'a'而mydf显示''和''?)

|S10同样,如果我用类型(比如说)进行初始化,file_name那么事情会在长度为 10 时被截断。

我能找到的唯一类似的问题是这个,但这会先验地计算适当的字符串长度,因此与我的不太一样(因为我事先一无所知)。

file_name除了用(例如)初始化|S9999999999999(即一些荒谬的上限)之外,还有其他选择吗?

4

1 回答 1

27

而不是使用STRINGdtype,总是可以使用object作为 dtype。这将允许将任何对象分配给数组元素,包括 Python 可变长度字符串。例如:

>>> import numpy as np
>>> mydf = np.empty( (2,), dtype=[('file_name',object),('file_size_mb',float)] )
>>> mydf['file_name'][0]='foobarasdf.tif'
>>> mydf['file_name'][1]='arghtidlsarbda.jpg'
>>> mydf
array([('foobarasdf.tif', 0.0), ('arghtidlsarbda.jpg', 0.0)], 
      dtype=[('file_name', '|O8'), ('file_size_mb', '<f8')])

具有可变长度元素是违反数组概念的精神的,但这是尽可能接近的。数组的想法是元素存储在内存中定义明确且间隔规则的内存地址,这禁止可变长度元素。通过将指向字符串的指针存储在数组中,可以规避这一限制。(这基本上就是上面的例子所做的。)

于 2012-02-02T09:08:38.010 回答