2017-01-24 11 views
3

Существует ли эффективный и питонический способ выбора из d-мерного массива всех элементов с четным индексом, не зная d заранее? И все остальные (т. Е. Все те, которые имеют хотя бы нечетный индекс)?numpy.array выбрать все четные элементы из d-мерного массива

Минимальный пример первого вопроса

import numpy as np 
a = np.array(range(27)).reshape((3,3,3)) 
a[::2,::2,::2] 
# -> array([[[ 0, 2], 
#   [ 6, 8]], 
#   [[18, 20], 
#   [24, 26]]]) 

только не-вещий способ я нашел для D-мерных объектов, d является переменным По крайней мере, на «все еще» стороны, " по крайней мере один странный «все еще ускользает от меня.

d = 3 
a = np.array(range(3**d)).reshape([3]*d) 
b = a 
for i in range(d): 
    b = np.take(b, np.array(range(0,b.shape[i],2)), axis=i) 

Причина, почему я спрашиваю это (что, возможно, уже имеет решение более высокого уровня) является то, что я хочу, чтобы итеративно создать большой d-мерный объект размером (2**n+1, ..., 2**n+1) в п шагов, на каждом шаге копирования элементы с четными индексами из предыдущих шагов, например:

for n in range(N): 
    new_array = np.zeros([2**n+1]*d) 
    new_array[all_even] = old_array 
    new_array[at_least_one_odd] = #something else 

Заранее благодарим за любой намек!

ответ

2

Вот подход, использующий np.ix_ -

a[np.ix_(*[range(0,i,2) for i in a.shape])] 

Sample пробегов -

In [813]: def even_idx(a): 
    ...:  return a[np.ix_(*[range(0,i,2) for i in a.shape])] 
    ...: 

In [814]: a = np.array(range(27)).reshape((3,3,3)) 

In [815]: np.allclose(a[::2,::2,::2], even_idx(a)) 
Out[815]: True 

In [816]: a = np.array(range(27*4)).reshape((3,3,3,4)) 

In [817]: np.allclose(a[::2,::2,::2,::2], even_idx(a)) 
Out[817]: True 

In [818]: a = np.array(range(27*4*5)).reshape((3,3,3,4,5)) 

In [819]: np.allclose(a[::2,::2,::2,::2,::2], even_idx(a)) 
Out[819]: True 
3

Я думаю, вы могли бы использовать объекты ломтика.

even = a[[slice(None, None, 2) for _ in range(a.ndim)]] 
odd = a[[slice(1, None, 2) for _ in range(a.ndim)]] 
+0

Спасибо за ответ, но, к сожалению, когда я пытаюсь запустить это я получаю некоторые предупреждения и ошибки, наиболее фундаментальным является то, что NumPy не имеет модуль «срез» ... хотя ответ на @Divakar уже удовлетворяющий моим потребностям (по крайней мере, для первого вопроса, я думаю, что второй не имеет удовлетворительного ответа) не могли бы вы объяснить обоснование вашего ответа, которое может быть полезно мне для понимания? Благодаря! –

+1

Извините, объекты среза являются встроенными Python. Я обновил свой ответ. Я думаю, это более читаемо. – miindlek

+0

Спасибо большое, это действительно приятно! Я не знал, что есть «срезная» встроенная система, которая заменяет фрагмент: нотация, это действительно полезно. Чтобы уточнить, вторая часть вопроса заключалась в том, чтобы иметь элементы с хотя бы одним нечетным индексом, а не всеми коэффициентами; в примере есть 27 элементов, из которых 8 даже, я наивно надеялся на способ получить оставшиеся 19 (которые были бы обязательно сглажены, поскольку они теряют любую форму). Но опять же, чем больше я думаю об этом и чем более необоснованно это кажется, поэтому я полностью доволен первой частью, спасибо! –