2014-01-23 2 views
1

Простите меня, если что-то о том, что я хотел спросить, звучит глупо, я только начал с Numpy и многомерными массивами в Python: DКак итерация 3D-Numpy массива

, что сказал, я У вас есть 3D-массив [85 x 235 x 327]. Каждая позиция имеет дискретное значение и, в большинстве случаев, NaN.

Первое, что я хотел бы сделать, это перебрать этот массив и удалить значения NaN, построив новый массив, содержащий только допустимые значения.

Я попытался это:

for index,value in np.ndenumerate(data): 
    print "index value: " + str(index) 
    print "value: " + str(value) 

Но это будет только выполнить один проход ... не совсем уверен, что ndenumerate делает.

попытался Также это:

indexOne = waves.shape[0] 
indexTwo = waves.shape[1] 
indexThree = waves.shape[2] 

for i in range(indexOne): 
    for j in range(indexTwo): 
     for k in range(indexThree): 
      a = waves[i,j,k] 
      print a.data 

И в то время как это делает перебирает ... принимая во внимание, что у меня есть 6531825 точек ... это будет длиться вечно ... Таким образом, есть ли встроенная в функции для удаления значений из существующего массива без необходимости повторять все элементы?

+1

Что вы подразумеваете под "удалить"? Это звучит так, будто вам нужен ровный массив, содержащий только значения, отличные от nan. Или вы хотите, чтобы значения заменялись чем-то другим? – senderle

+0

Прочитали ли вы http://wiki.scipy.org/Tentative_NumPy_Tutorial или http://scipy-lectures.github.io/intro/numpy/index.html? Я думаю, вы найдете это полезным. – YXD

+0

@senderle Я просто хочу избавиться от этих значений, имея окончательный массив со всеми значениями, сохраняя форму, если это возможно, в противном случае - плоский массив. – AlejandroVK

ответ

1

Это зависит немного от того, что вы хотите, чтобы окончательный массив выглядеть. Вот что-то, что буквально делает то, что вы говорите. Однако он не сохраняет форму. Настройка массива:

>>> a = numpy.linspace(0, 26, 27).reshape(3, 3, 3) 
>>> a[1][0] = numpy.nan 
>>> a 
array([[[ 0., 1., 2.], 
     [ 3., 4., 5.], 
     [ 6., 7., 8.]], 

     [[ nan, nan, nan], 
     [ 12., 13., 14.], 
     [ 15., 16., 17.]], 

     [[ 18., 19., 20.], 
     [ 21., 22., 23.], 
     [ 24., 25., 26.]]]) 

Затем вы можете создать маску с isnan:

>>> numpy.isnan(a) 
array([[[False, False, False], 
     [False, False, False], 
     [False, False, False]], 

     [[ True, True, True], 
     [False, False, False], 
     [False, False, False]], 

     [[False, False, False], 
     [False, False, False], 
     [False, False, False]]], dtype=bool) 

и использовать его для индекса a:

>>> a[~numpy.isnan(a)] 
array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 12., 13., 
     14., 15., 16., 17., 18., 19., 20., 21., 22., 23., 24., 
     25., 26.]) 

Вы можете использовать подобный трюк, чтобы сделать много других вещей с nan значениями. Например:

>>> a[numpy.isnan(a)] = 0 
>>> a 
array([[[ 0., 1., 2.], 
     [ 3., 4., 5.], 
     [ 6., 7., 8.]], 

     [[ 0., 0., 0.], 
     [ 12., 13., 14.], 
     [ 15., 16., 17.]], 

     [[ 18., 19., 20.], 
     [ 21., 22., 23.], 
     [ 24., 25., 26.]]]) 
+0

Хорошо, спасибо за подробный ответ ... это желательно с массивом размером с мой?С моей точки зрения, я не против потерять форму, поскольку, если у меня нет никаких ценностей ... Я не против потерять эту колонку. – AlejandroVK

+0

Это правда, что это создает второй логический массив того же размера, что и оригинал; два массива с 6 миллионами элементов не слишком много подходят для большинства современных компьютеров. Тем не менее, в 'numpy' есть много функций, связанных с nan, которые могут помочь уменьшить использование памяти, если вам это нужно. Например, вы можете создать «маскированный массив», используя ['numpy.ma.masked_invalid'] (http://docs.scipy.org/doc/numpy/reference/generated/numpy.ma.masked_invalid.html#numpy. ma.masked_invalid); Маскированный массив занимает больше памяти, но может сохранять память или быть более эффективным в некоторых операциях. – senderle

+0

Спасибо, senderle, это эффективно работает. Любая идея о том, как numpy выравнивает многомерный массив в 1D? Просто интересно, сколько «информации» я теряю в процессе: D – AlejandroVK

1

nan_to_num делает именно то, что вы хотите:

Заменить нан с нуля и инф с конечным числом.

Возвращает массив или скалярная замену не является числом (NAN) с нулевым, (положительной) бесконечностью с очень большим числом и отрицательной бесконечностью с очень малым (или отрицательным) числом.

использовать его как:

x = np.nan_to_num(x) 
+0

Спасибо, я дам ему попробовать – AlejandroVK

Смежные вопросы