这里不需要正则表达式。只需将数组转换为 1 字节字符串,使用astype
-
v = np.array(['abc', 'def', 'ghi'])
>>> v.astype('<U1')
array(['a', 'd', 'g'],
dtype='<U1')
或者,您可以更改其view
并大步迈进。这是针对相同大小的字符串的稍微优化的版本。 -
>>> v.view('<U1')[::len(v[0])]
array(['a', 'd', 'g'],
dtype='<U1')
这是更通用的版本.view
方法,但这适用于不同长度的字符串数组。感谢 Paul Panzer 的帮助建议 -
>>> v.view('<U1').reshape(v.shape + (-1,))[:, 0]
array(['a', 'd', 'g'],
dtype='<U1')
表现
y = np.array([x * 20 for x in v]).repeat(100000)
y.shape
(300000,)
len(y[0]) # they're all the same length - `abcabcabc...`
60
现在,时间安排——
# `astype` conversion
%timeit y.astype('<U1')
100 loops, best of 3: 5.03 ms per loop
# `view` for equal sized string arrays
%timeit y.view('<U1')[::len(y[0])]
100000 loops, best of 3: 2.43 µs per loop
# Paul Panzer's version for differing length strings
%timeit y.view('<U1').reshape(y.shape + (-1,))[:, 0]
100000 loops, best of 3: 3.1 µs per loop
The view
方法是速度大幅提升.
但是,请谨慎使用,因为内存是共享的。
如果您对更通用的解决方案感兴趣,可以找到您第一个字母(无论它在哪里),我想说最快/最简单的方法是使用re
模块,编译模式并在列表理解中搜索。
>>> p = re.compile('[a-zA-Z]')
>>> [p.search(x).group() for x in v]
['a', 'd', 'g']
而且,它在上述相同设置下的性能 -
%timeit [p.search(x).group() for x in y]
1 loop, best of 3: 320 ms per loop