说我有以下内容:
my_list = np.array(["abc", "def", "ghi"])
我想得到:
np.array(["ef", "hi"])
我试过了:
my_list[1:,1:]
但后来我得到了:
IndexError: too many indices for array
Numpy是否支持切片?
答案 0 :(得分:2)
不,你不能这样做。对于numpy np.array(["abc", "def", "ghi"])
是一维字符串数组,因此您不能使用2D切片。
您可以将数组定义为2D数组或字符,或者只使用列表理解进行切片,
In [4]: np.asarray([el[1:] for el in my_list[1:]])
Out[4]:
array(['ef', 'hi'], dtype='|S2')
答案 1 :(得分:0)
根据Joe Kington here,python非常擅长字符串操作,并且生成器/列表理解对于字符串操作来说是快速且灵活的。除非您需要在管道中稍后使用numpy
,否则我会反对它。
[s[1:] for s in my_list[1:]]
快:
In [1]: from string import ascii_lowercase
In [2]: from random import randint, choice
In [3]: my_list_rand = [''.join([choice(ascii_lowercase)
for _ in range(randint(2, 64))])
for i in range(1000)]
In [4]: my_list_64 = [''.join([choice(ascii_lowercase) for _ in range(64)])
for i in range(1000)]
In [5]: %timeit [s[1:] for s in my_list_rand[1:]]
10000 loops, best of 3: 47.6 µs per loop
In [6]: %timeit [s[1:] for s in my_list_64[1:]]
10000 loops, best of 3: 45.3 µs per loop
使用numpy
只会增加开销。
答案 2 :(得分:0)
您的字符串数组将数据存储为连续的字符块,使用“S3”dtype将其划分为长度为3的字符串。
In [116]: my_list
Out[116]:
array(['abc', 'def', 'ghi'],
dtype='|S3')
S1,S2
dtype将每个元素视为2个字符串,每个字符串分别为1和2个字符:
In [115]: my_list.view('S1,S2')
Out[115]:
array([('a', 'bc'), ('d', 'ef'), ('g', 'hi')],
dtype=[('f0', 'S1'), ('f1', 'S2')])
选择第二个字段以获得具有所需字符的数组:
In [114]: my_list.view('S1,S2')[1:]['f1']
Out[114]:
array(['ef', 'hi'],
dtype='|S2')
我对view
的第一次尝试是将数组拆分为单字节字符串,然后使用生成的2d数组:
In [48]: my_2dstrings = my_list.view(dtype='|S1').reshape(3,-1)
In [49]: my_2dstrings
Out[49]:
array([['a', 'b', 'c'],
['d', 'e', 'f'],
['g', 'h', 'i']],
dtype='|S1')
然后可以在两个维度中切割此数组。我使用flatten
删除维度,并强制复制(以获取新的连续缓冲区)。
In [50]: my_2dstrings[1:,1:].flatten().view(dtype='|S2')
Out[50]:
array(['ef', 'hi'],
dtype='|S2')
如果字符串已经在数组中(而不是列表),那么这种方法比列表理解方法快得多。
一些1000 x 64列表wflynny
测试
In [98]: timeit [s[1:] for s in my_list_64[1:]]
10000 loops, best of 3: 173 us per loop # mine's slower computer
In [99]: timeit np.array(my_list_64).view('S1').reshape(64,-1)[1:,1:].flatten().view('S63')
1000 loops, best of 3: 213 us per loop
In [100]: %%timeit arr =np.array(my_list_64)
.....: arr.view('S1').reshape(64,-1)[1:,1:].flatten().view('S63') .....:
10000 loops, best of 3: 23.2 us per loop
从列表中创建数组很慢,但一旦创建,view
方法就会快得多。
请参阅我之前关于np.char
的说明的编辑历史记录。
答案 3 :(得分:-2)
您的切片语法不正确。您只需my_list[1:]
即可获得所需内容。如果要将元素两次复制到列表中,可以执行something = mylist[1:].extend(mylist[1:])