Numpy字符串编码

Rom*_*man 5 python string numpy python-3.x

模块numpy是一个出色的工具,可以高效地存储python对象,其中包括字符串.对于numpy数组中的ANSI字符串,每个字符仅使用1个字节.

但是,有一个不便之处.存储对象的类型不多string但是bytes,这意味着在大多数情况下必须进行解码以便进一步使用,这反过来意味着相当庞大的代码:

>>> import numpy
>>> my_array = numpy.array(['apple', 'pear'], dtype = 'S5')
>>> print("Mary has an {} and a {}".format(my_array[0], my_array[1]))
Mary has an b'apple' and a b'pear'
>>> print("Mary has an {} and a {}".format(my_array[0].decode('utf-8'),
... my_array[1].decode('utf-8')))
Mary has an apple and a pear
Run Code Online (Sandbox Code Playgroud)

使用其他数据类型可以消除这种不便,例如:

>>> my_array = numpy.array(['apple', 'pear'], dtype = 'U5')
>>> print("Mary has an {} and a {}".format(my_array[0], my_array[1]))
Mary has an apple and a pear
Run Code Online (Sandbox Code Playgroud)

但是,这只能通过内存使用量增加4倍来实现:

>>> numpy.info(my_array)
class:  ndarray
shape:  (2,)
strides:  (20,)
Run Code Online (Sandbox Code Playgroud)
itemsize:  20
aligned:  True
contiguous:  True
fortran:  True
data pointer: 0x1a5b020
byteorder:  little
byteswap:  False
type: <U5
Run Code Online (Sandbox Code Playgroud)

是否有一个解决方案结合了有效的内存分配和ANSI字符串的方便使用的优点?

hpa*_*ulj 4

它与 相比并没有很大的区别decode,但是astype可以工作(并且可以应用于整个数组而不是每个字符串)。但只要需要,较长的阵列就会保留下来。

In [538]: x=my_array.astype('U');"Mary has an {} and a {}".format(x[0],x[1])
Out[538]: 'Mary has an apple and a pear'
Run Code Online (Sandbox Code Playgroud)

我在语法中找不到任何format可以强制减少“b”格式的内容。

/sf/answers/1390535121/ - 展示如何自定义 Formatter 类,更改format_field方法。我尝试了类似的方法convert_field。但调用语法还是很乱。

In [562]: def makeU(astr):
    return astr.decode('utf-8')
   .....: 

In [563]: class MyFormatter(string.Formatter):
    def convert_field(self, value, conversion):
        if 'q'== conversion:
            return makeU(value)
        else:
            return super(MyFormatter, self).convert_field(value, conversion)
   .....:         

In [564]: MyFormatter().format("Mary has an {!q} and a {!q}",my_array[0],my_array[1])
Out[564]: 'Mary has an apple and a pear'
Run Code Online (Sandbox Code Playgroud)

进行此格式化的其他几种方法:

In [642]: "Mary has an {1} and a {0} or {1}".format(*my_array.astype('U'))
Out[642]: 'Mary has an pear and a apple or pear'
Run Code Online (Sandbox Code Playgroud)

这会(即时)转换数组并将其作为format列表传递。如果数组已经是 unicode,它也可以工作:

In [643]: "Mary has an {1} and a {0} or {1}".format(*uarray.astype('U'))
Out[643]: 'Mary has an pear and a apple or pear'
Run Code Online (Sandbox Code Playgroud)

np.char具有将字符串函数应用于字符数组元素的函数。这样decode就可以应用于整个数组:

In [644]: "Mary has a {1} and an {0}".format(*np.char.decode(my_array))
Out[644]: 'Mary has a pear and an apple'
Run Code Online (Sandbox Code Playgroud)

(如果数组已经是 unicode,则这不起作用)。

如果您对字符串数组做了很多工作,np.char那么值得研究一下。