从numpy数组中的每个字符串中提取第一个字母

She*_*hew 3 python arrays string numpy

我有一个巨大的numpy数组,其中元素是字符串.我喜欢用字符串的第一个字母替换字符串.例如,如果

C [0] ='A90CD'

我想用它替换它

C[0] = 'A'
Run Code Online (Sandbox Code Playgroud)

简而言之,我正在考虑在循环中应用正则表达式,其中我有一个正则表达式的字典,如

'^ A.+ $'=>'A'

'^ B.+ $'=>'B'等

如何在numpy数组上应用此正则表达式?或者有没有更好的方法来实现相同的目标?

cs9*_*s95 8

这里不需要正则表达式.只需将您的数组转换为1字节字符串,使用astype-

v = np.array(['abc', 'def', 'ghi'])
Run Code Online (Sandbox Code Playgroud)

>>> v.astype('<U1')
array(['a', 'd', 'g'],
      dtype='<U1')
Run Code Online (Sandbox Code Playgroud)

或者,你改变它的view步伐.这是针对等大小字符串的略微优化版本.-

>>> v.view('<U1')[::len(v[0])]
array(['a', 'd', 'g'],
      dtype='<U1')
Run Code Online (Sandbox Code Playgroud)

这里是更通用的.view方法版本,但这适用于长度不同的字符串数组.感谢Paul Panzer提出的建议 -

>>> v.view('<U1').reshape(v.shape + (-1,))[:, 0]
array(['a', 'd', 'g'],
      dtype='<U1')
Run Code Online (Sandbox Code Playgroud)

性能

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
Run Code Online (Sandbox Code Playgroud)

现在,时间 -

# `astype` conversion

%timeit y.astype('<U1')
100 loops, best of 3: 5.03 ms per loop
Run Code Online (Sandbox Code Playgroud)

# `view` for equal sized string arrays 

%timeit y.view('<U1')[::len(y[0])]
100000 loops, best of 3: 2.43 µs per loop
Run Code Online (Sandbox Code Playgroud)

# 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
Run Code Online (Sandbox Code Playgroud)

view方法的速度更快.

但是,请谨慎使用,因为内存是共享的.


如果您对找到第一个字母(无论它在哪里)的更通用的解决方案感兴趣,我会说最快/最简单的方法是使用re模块,编译模式并在列表理解中搜索.

>>> p = re.compile('[a-zA-Z]')
>>> [p.search(x).group() for x in v]
['a', 'd', 'g']
Run Code Online (Sandbox Code Playgroud)

并且,它在上述相同设置中的性能 -

%timeit [p.search(x).group() for x in y]
1 loop, best of 3: 320 ms per loop
Run Code Online (Sandbox Code Playgroud)

  • 字符串的长度不必相同,以便视图转换工作.只需执行`strarr.view('<U1').reshape(strarr.shape +( - 1,))[...,0]`,并可能警告数据是共享的. (3认同)