Numpy字符串编码

2024-05-15 20:53:31 发布

您现在位置:Python中文网/ 问答频道 /正文

模块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

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

>>> 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

然而,这只能通过将内存使用量增加4倍来实现:

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

有没有一种解决方案可以将高效的内存分配和方便地使用ANSI字符串的优点结合起来?


Tags: and对象字符串numpyantrueformatapple
2条回答

它与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'

我在format语法中找不到任何强制使用“b”格式的内容。

https://stackoverflow.com/a/19864787/901925 -演示如何自定义格式化程序类,更改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'

其他两种格式化方法:

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'

这将转换数组(动态)并将其作为列表传递给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'

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'

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

如果你经常使用字符串数组,np.char是值得研究的。

给出:

>>> my_array = numpy.array(['apple', 'pear'], dtype = 'S5')

你可以在飞行中解码:

>>> print("Mary has an {} and a {}".format(*map(lambda b: b.decode('utf-8'), my_array)))
Mary has an apple and a pear

或者可以创建特定的格式化程序:

import string
class ByteFormatter(string.Formatter):
    def __init__(self, decoder='utf-8'):
        self.decoder=decoder

    def format_field(self, value, spec):
        if isinstance(value, bytes):
            return value.decode(self.decoder)
        return super(ByteFormatter, self).format_field(value, spec)   

>>> print(ByteFormatter().format("Mary has an {} and a {}", *my_array))
Mary has an apple and a pear

相关问题 更多 >