Ваш массив строк хранит данные в виде непрерывного блока символов, используя DTYPE в «S3», чтобы разделить его на строки длины 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')])
выбрать 2-ю поле, чтобы получить массив с нужными символами:
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 х 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
.
Обратите внимание, что я говорю о многомерном разрезе в Numpy, что позволяет использовать синтаксис, который я использовал. Кроме того, 'my_list [1:]' получает меня '['def', 'ghi']', а не '['ef', 'hi']'. – Ben