Инициализация матрицы numpy на что-то отличное от нуля или единицы
У меня есть следующий код:
r = numpy.zeros(shape = (width, height, 9))
он создает матрицу ширины x высоты x 9, заполненную нулями. Вместо этого я хотел бы знать, есть ли функция или способ инициализировать их вместо NaN.
есть ли? Не прибегая к ручному выполнению петель и тому подобного?
спасибо
7 ответов:
вам редко нужны петли для векторных операций в numpy. Вы можете создать неинициализированный массив и назначить всем записям сразу:
>>> a = numpy.empty((3,3,)) >>> a[:] = numpy.nan >>> a array([[ NaN, NaN, NaN], [ NaN, NaN, NaN], [ NaN, NaN, NaN]])
Я рассчитал альтернативы
a[:] = numpy.nanздесьa.fill(numpy.nan)как опубликовано Blaenk:$ python -mtimeit "import numpy as np; a = np.empty((100,100));" "a.fill(np.nan)" 10000 loops, best of 3: 54.3 usec per loop $ python -mtimeit "import numpy as np; a = np.empty((100,100));" "a[:] = np.nan" 10000 loops, best of 3: 88.8 usec per loopтайминги показывают предпочтение для
ndarray.fill(..)как более быстрая альтернатива. OTOH, мне нравится удобная реализация numpy, где вы можете назначать значения целым срезам в то время, намерение кода очень ясно.
другой вариант-использовать
numpy.full, опция доступна в NumPy 1.8+a = np.full([height, width, 9], np.nan)Это довольно гибкие и вы можете заполнить его с любым другим номером, который вы хотите.
вы знакомы с
numpy.nan?вы можете создать свой собственный метод, таких как:
def nans(shape, dtype=float): a = numpy.empty(shape, dtype) a.fill(numpy.nan) return aзатем
nans([3,4])выводит
array([[ NaN, NaN, NaN, NaN], [ NaN, NaN, NaN, NaN], [ NaN, NaN, NaN, NaN]])Я нашел этот код список рассылки нить.
Я сравнил предложенные альтернативы для скорости и обнаружил, что для достаточно больших векторов/матриц для заполнения все альтернативы, кроме
val * onesиarray(n * [val])одинаково быстро.
код для воспроизведения сюжета:
import numpy import perfplot val = 42.0 def fill(n): a = numpy.empty(n) a.fill(val) return a def colon(n): a = numpy.empty(n) a[:] = val return a def full(n): return numpy.full(n, val) def ones_times(n): return val * numpy.ones(n) def list(n): return numpy.array(n * [val]) perfplot.show( setup=lambda n: n, kernels=[fill, colon, full, ones_times, list], n_range=[2**k for k in range(20)], logx=True, logy=True, xlabel='len(a)' )
вы всегда можете использовать умножение, если вы сразу не вспомнить
.emptyили.fullметоды:>>> np.nan * np.ones(shape=(3,2)) array([[ nan, nan], [ nan, nan], [ nan, nan]])конечно, он работает и с любым другим числовым значением:
>>> 42 * np.ones(shape=(3,2)) array([[ 42, 42], [ 42, 42], [ 42, 42]])но @u0b34a0f6ae принято отвечать в 3 раза быстрее (циклы процессора, а не мозговые циклы для запоминания синтаксиса numpy;):
$ python -mtimeit "import numpy as np; X = np.empty((100,100));" "X[:] = np.nan;" 100000 loops, best of 3: 8.9 usec per loop (predict)laneh@predict:~/src/predict/predict/webapp$ master $ python -mtimeit "import numpy as np; X = np.ones((100,100));" "X *= np.nan;" 10000 loops, best of 3: 24.9 usec per loop
Как сказано, numpy.пустой () - это путь. Однако для объектов fill () может не делать именно то, что вы думаете:
In[36]: a = numpy.empty(5,dtype=object) In[37]: a.fill([]) In[38]: a Out[38]: array([[], [], [], [], []], dtype=object) In[39]: a[0].append(4) In[40]: a Out[40]: array([[4], [4], [4], [4], [4]], dtype=object)один из способов может быть, например:
In[41]: a = numpy.empty(5,dtype=object) In[42]: a[:]= [ [] for x in range(5)] In[43]: a[0].append(4) In[44]: a Out[44]: array([[4], [], [], [], []], dtype=object)
еще одна возможность, еще не упомянутая здесь, заключается в использовании плитки NumPy:
a = numpy.tile(numpy.nan, (3, 3))дает
array([[ NaN, NaN, NaN], [ NaN, NaN, NaN], [ NaN, NaN, NaN]])Я не знаю о сравнении скорости.

Comments