转换NumPy列表np.uint8公司数组到np.unicode\阵列

2024-04-25 23:58:02 发布

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

我有一个带有dtype=np.uint8的NumPy可变大小数组的列表(这些数组表示UTF-8编码的字符串)。如何高效快速地将此列表转换为单个dtype=np.unicode_数组?在

l = [np.frombuffer(b'asd', dtype = np.uint8), np.frombuffer(b'asdasdas', dtype = np.uint8)]

# The following will work, but will first create a temporary string which is inefficient. 
# I'm looking for a method that would directly allocate a target np.unicode_-typed array 
# and encode the data into it.
a = np.array([s.tostring().decode('utf-8') for s in l])

数组不仅仅是ASCII编码的,它们还包含其他字符:

^{pr2}$

Tags: 字符串numpy编码列表fornpunicode数组
1条回答
网友
1楼 · 发布于 2024-04-25 23:58:02

更新

原来pythonutf-8编解码器可以用来解码 直接使用ndarray,无需复制其内容 首先使用.tostring()对bytestring:使用编解码器 模块可以检索 将utf-8字节序列转换为unicode字符串 必须经过str.decode

lst = [np.frombuffer(b'asd', dtype = np.uint8), np.frombuffer(b'asdasdas', dtype = np.uint8)]

import codecs

decoder = codes.getdecoder("utf-8")    
data = np.array([decoder(item)[0] for item in lst], dtype="unicode")

这避免了转换的一个步骤-还有另一个步骤可以 请避免,因为这仍然会创建内存中所有字符串的列表 在调用最后一个.array构造函数之前,numpy有一个.fromiter数组构造函数,但它不能用任意unicode对象创建数组-它需要一个固定的字符宽度。这样会消耗比目前更多的内存:

^{pr2}$

原创-答案(大多是罗马漫话)

现代Python对Unicode文本的内部处理非常高效,内部Unicode点表示依赖于字符串中最宽的字符。在

另一方面,Numpy只为每个unicode字符存储一个32位的值,它没有业务“理解”utf-8。Python语言做得很快。虽然Python在将utf-8字节解码为文本时不会使用任何多线程、多核或硬件加速的策略,但是解码是在本机代码中进行的,并且速度与在单个CPU内核中的速度一样快。在

在我的系统中,使用纯Python将4MB大小的文本解码为unicode只需不到30毫秒。在

换句话说:你担心的是一个错误的问题——除非你正在编写的代码需要以持续的方式每秒转换大约100个圣经大小的文本语料库。在

只需让Python执行utf-8解码,并将结果处理回numpy(它将以其32位格式再次对其进行编码)-对于大多数实际任务来说,在这方面的花费是微不足道的,例如,Pandas库就是这样做的,对数据执行几乎所有操作:在每次操作后创建数据的新副本。在

相关问题 更多 >