В основном , вы можете это сделать, но вы, вероятно, не должны в большинстве случаев - выгоды не такие огромные, а много вещей в numpy
сложнее с несмежными данными.
Тем не менее, это не сложно сделать, что вы хотите - вы можете использовать аргумент strides
, выставленный ndarray
. Скажем, мы начинаем с массива, в котором есть некоторые вкусные яблоки, но много других крутых. Как мы получаем яблоки?
>>> xapplesx = numpy.array(list('xxxaxpxpxlxexsxxx'))
>>> xapplesx
array(['x', 'x', 'x', 'a', 'x', 'p', 'x', 'p', 'x', 'l', 'x', 'e', 'x',
's', 'x', 'x', 'x'],
dtype='|S1')
Мы хотим начать с индексом 3
, и мы хотим, чтобы все другие ценности и положить его в одномерном зрения, это означает, что мы хотим, чтобы принимать все значения 2
й.
Так мы проходим offset=3
и strides=(2,)
:
>>> apples = numpy.ndarray(shape=(6,), dtype='|S1',
buffer=xapplesx, offset=3, strides=(2,))
>>> apples
array(['a', 'p', 'p', 'l', 'e', 's'],
dtype='|S1')
Привыкание к использованию strides
непосредственно этот путь занимает немного тщательного мышления. Предположим, мы хотим получить наши яблоки и положить их на x
s. Теперь нам нужен двумерный массив, и мы должны указать шаги для обоих измерений. Но мы хотим, чтобы вторая строка данных содержала значения, которые поступают сразу после яблок. Таким образом, мы задаем большой шаг только 1
для этого измерения:
>>> applesoverx = numpy.ndarray(shape=(2, 6), dtype='|S1',
buffer=xapplesx, offset=3, strides=(1, 2))
>>> applesoverx
array([['a', 'p', 'p', 'l', 'e', 's'],
['x', 'x', 'x', 'x', 'x', 'x']],
dtype='|S1')
Если у вас возникли проблемы при получении правильные данные buffer
, вероятно, можно сделать что-то вроде этого:
>>> a = np.arange(12).reshape(4,3)[::-1,:]
>>> x = np.ndarray(shape=a.shape, buffer=a.base.data,
strides=a.strides, offset=72, dtype=a.dtype)
Единственный трюк что вам нужно выработать правильное смещение. В результате (я уверен) идеальный клон:
>>> x
array([[ 9, 10, 11],
[ 6, 7, 8],
[ 3, 4, 5],
[ 0, 1, 2]])
>>> a
array([[ 9, 10, 11],
[ 6, 7, 8],
[ 3, 4, 5],
[ 0, 1, 2]])
>>> x.shape
(4, 3)
>>> a.shape
(4, 3)
>>> x.strides
(-24, 8)
>>> a.strides
(-24, 8)
>>> id(x.base)
140602344736320
>>> id(a.base)
140602344736320
Если вы хотите, чтобы сделать копию исходных данных, вы можете использовать a.base.copy().data
в качестве аргумента buffer
. И (как Лука указал), вы можете определить смещение (см выше) с этим:
a.__array_interface__['data'][0] - a.base.__array_interface__['data'][0]
Это дает вам ссылку на указатель, на котором буфер начинается для данного массива, как описано here.
Работает ли '.copy()'? Если нет, когда это неправильно? – hpaulj
'copy' переустанавливает данные как смежный, c-упорядоченный массив (другими словами, он не сохраняет существующий макет памяти). – Luke
Как насчет 'order = 'K''? – hpaulj