NumPy字符串数组的索引行为

7

我有一个字符串数组

>>> lines
array(['RL5\\Stark_223', 'RL5\\Stark_223', 'RL5\\Stark_223', ...,
       'RL5\\Stark_238', 'RL5\\Stark_238', 'RL5\\Stark_238'], 
      dtype='|S27')

为什么我可以通过索引字符串来获取第一个数组元素?
>>> lines[0][0:3]
'RL5'

但对于所有数组元素,它们不会被放置在相同的位置。

>>> lines[:][0:3]
array(['RL5\\Stark_223', 'RL5\\Stark_223', 'RL5\\Stark_223'], 
      dtype='|S27')

有人能提供一种方法来获得以下结果:

数组(['RL5','RL5','RL5',... 'RL5','RL5'])

5个回答

5

要提取每个字符串的前n个字符,您可以滥用.astype

>>> s = np.array(['RL5\\Stark_223', 'RL5\\Stark_223', 'RL5\\Stark_223'])
>>> s
array(['RL5\\Stark_223', 'RL5\\Stark_223', 'RL5\\Stark_223'], 
      dtype='|S13')
>>> s.astype('|S3')
array(['RL5', 'RL5', 'RL5'], 
      dtype='|S3')

不知道为什么这个答案这么难找!简单明了,感谢! - isosceleswheel

3

别忘了 chararray!

lines.view(np.chararray).ljust(3)
chararray(['RL5', 'RL5', 'RL5', 'RL5', 'RL5', 'RL5'], 
      dtype='|S3')

尽管它的速度奇慢无比:

#Extend lines to 600000 elements

%timeit lines.view(np.chararray).ljust(3)
1 loops, best of 3: 542 ms per loop

%timeit np.vectorize(lambda x: x[:3])(lines)
1 loops, best of 3: 239 ms per loop

%timeit map(lambda s: s[0:3], lines)
1 loops, best of 3: 243 ms per loop

%timeit arr.astype('|S3')
100 loops, best of 3: 4.72 ms per loop

可能是因为它在复制数据,这样做的好处是输出数组的dtype被最小化: S3 vs S64

1
尝试这个。
map(lambda s:s[0:3],lines)

0
你可以使用numpy的vectorize
In [11]: np.vectorize(lambda x: x[:3])(lines)
Out[11]: 
array(['RL5', 'RL5', 'RL5', 'RL5', 'RL5', 'RL5'], 
      dtype='|S64')

0
如果你想要更快速和(稍微)更灵活,可以尝试:
lines.view('|S1').reshape(-1, lines.dtype.itemsize)[:, :3].reshape(-1).view('|S3')

这可以用于更任意的切片和切块。

时间信息:

import numpy as np
lines = np.array(['RL5\\Stark_223', 'RL5\\Stark_223', 'RL5\\Stark_223', 
'RL5\\Stark_238', 'RL5\\Stark_238', 'RL5\\Stark_238'], dtype='|S27').repeat(100000)

%timeit lines.view(np.chararray).ljust(3)
1 loop, best of 3: 231 ms per loop

%timeit np.vectorize(lambda x: x[:3])(lines)
1 loop, best of 3: 226 ms per loop

%timeit map(lambda s: s[0:3], lines)
1 loop, best of 3: 171 ms per loop

%timeit lines.astype('|S3')
100 loops, best of 3: 3.58 ms per loop

%timeit lines.view('|S1').reshape(-1, lines.dtype.itemsize)[:, :3].reshape(-1).view('|S3')
100 loops, best of 3: 5.16 ms per loop

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