如何在 numpy 中创建字符数组?
Posted
技术标签:
【中文标题】如何在 numpy 中创建字符数组?【英文标题】:How do I create character arrays in numpy? 【发布时间】:2012-03-17 14:54:33 【问题描述】:假设我有以下数组:
import numpy as np
a = ['hello','snake','plate']
我希望它变成一个 numpy 数组 b
以便:
b[0,0] = 'h'
b[0,1] = 'e'
b[0,2] = 'l'
b[1,0] = 's'
...
我希望标准的 numpy 技巧起作用,例如广播、比较等。
它是如何完成的?这在 numpy 文档中的什么位置?
谢谢!
乌里
【问题讨论】:
【参考方案1】:将字符串长度指定为形状参数,unicode 1 char
> string_array = ['..##.#..#.', '##..#.....', '#...##..#.', '####.#...#', '##.##.###.', '##...#.###', '.#.#.#..##', '..#....#..', '###...#.#.', '..###..###']
> numpy.array(string_array,dtype=('U1',10))
array([['.', '.', '#', '#', '.', '#', '.', '.', '#', '.'],
['#', '#', '.', '.', '#', '.', '.', '.', '.', '.'],
['#', '.', '.', '.', '#', '#', '.', '.', '#', '.'],
['#', '#', '#', '#', '.', '#', '.', '.', '.', '#'],
['#', '#', '.', '#', '#', '.', '#', '#', '#', '.'],
['#', '#', '.', '.', '.', '#', '.', '#', '#', '#'],
['.', '#', '.', '#', '.', '#', '.', '.', '#', '#'],
['.', '.', '#', '.', '.', '.', '.', '#', '.', '.'],
['#', '#', '#', '.', '.', '.', '#', '.', '#', '.'],
['.', '.', '#', '#', '#', '.', '.', '#', '#', '#']], dtype='<U1')
这显然不应该奏效 - https://github.com/numpy/numpy/issues/18407 并在 numpy 1.20.1 中停止工作,但一个简单的替换是
numpy.array(list(map(list, string_array)))
在 numpy 接收之前将字符串列表转换为 char 列表的列表,避免了显式设置 dtype 的需要。
【讨论】:
我认识这个输入!它是来自Advent of Code 2020 Day 20 的样本数据中的第一个图块。【参考方案2】:实际上,您可以在 numpy 中不使用任何副本或列表推导来执行此操作(除了关于非等长字符串的警告......)。只需将其视为 1 个字符的字符串数组并对其进行整形:
import numpy as np
x = np.array(['hello','snake','plate'], dtype=str)
y = x.view('S1').reshape((x.size, -1))
print repr(y)
这会产生:
array([['h', 'e', 'l', 'l', 'o'],
['s', 'n', 'a', 'k', 'e'],
['p', 'l', 'a', 't', 'e']],
dtype='|S1')
不过,一般来说,在大多数情况下,我会避免使用 numpy 数组来存储字符串。在某些情况下它很有用,但您通常最好坚持使用允许可变长度字符串的数据结构,好吧,保存字符串。
【讨论】:
对于 python3,如果字符串是 ascii 字符串,则需要编写 dtype=bytes 如果你想让 Unicode 字符串工作,改变 dtype=np.unicode_ 和 view('U1')【参考方案3】:您可以直接创建一个numpy字符数组,例如:
b = np.array([ ['h','e','l','l','o'],['s','n','a','k','e'],['p','l','a','t','e'] ])
通常的数组技巧适用于此。
如果您有a
并希望从中生成 b,请注意:
list('hello') == ['h','e','l','l','o']
所以你可以这样做:
b = np.array([ list(word) for word in a ])
但是,如果a
有不等长的单词(例如['snakes','on','a','plane']
),你想如何处理较短的单词?您可以用空格填充最长的单词:
wid = max(len(w) for w in a)
b = np.array([ list(w.center(wid)) for w in a])
string.center(width)
用空格填充,使字符串居中。您也可以使用rjust
或ljust
(参见string docs)。
【讨论】:
谢谢,这可能对我有用。但我想知道是否有一种方法我不必使用列表理解?我将不得不多次执行此操作(要启动更大的阵列)。是否有一个 numpy 命令可以处理已编译代码中的循环? 我不知道有任何 numpy 命令专门将字符串拆分为单个字母,同时强制转换为矩阵。我认为您可能会被列表推导所困(但我们会看到,也许有人知道这样做的魔术函数)。以上是关于如何在 numpy 中创建字符数组?的主要内容,如果未能解决你的问题,请参考以下文章