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

3
我有一个巨大的numpy数组,其中元素是字符串。我希望用字符串的第一个字母替换这些字符串。例如,如果C [0] ='A90CD',我想将其替换为'A'。
C[0] = 'A'

简而言之,我想在循环中应用正则表达式,其中我有一个正则表达式字典,如下所示:

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

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

我该如何将此正则表达式应用于numpy数组?或者是否有更好的方法来实现相同的功能?

所有字符串都以字母开头吗?还是你想提取像02AC9这样的字符串的第一个字母? - Mr. T
是的,所有字符串都以字母开头。但实际上,我只对字符串的第一个字母感兴趣。 - Shew
那么,你从Coldspeed那里得到了答案。 - Mr. T
你的数组中的所有字符串长度都相等吗? - cs95
是的,所有字符串长度相同。 - Shew
1个回答

10

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

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

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

1
.view切片不会占用额外的内存,它只是指针。.astype会复制一份数据。此外,.view还可以让你更改那些首字母。 - Daniel F
3
字符串的长度不需要相同才能进行视图转换。只需执行strarr.view('<U1').reshape(strarr.shape + (-1,))[..., 0],可能需要警告数据共享。 - Paul Panzer
@DanielF "作为额外的好处" 或者是一个踢到自己脚的机会;-) - Paul Panzer
1
@cᴏʟᴅsᴘᴇᴇᴅ 我认为这并不奇怪,因为据我所知,numpy会将所有字符串填充到相同的长度。请尝试使用np.array('Hi, I am an example.'.split()).view('<U1') - Paul Panzer
如果字符串由数字组成怎么办?在这种情况下,<U1将产生前两个数字rt?我怎样才能得到一个数字? - Shew
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接