Официальное руководство по началу работы с NumPy (перевод)

машинное обучение Python NumPy SciPy
Официальное руководство по началу работы с NumPy (перевод)

Спереди написано: Изначально это было для учебы.NumPy, смотрите официальный сайтРуководство по началу работыЯ хочу проследить за экспериментом, боюсь, что им не часто пользуются, да и я забывчивый, поэтому записал. Просто следите за переводом, вы также можете улучшить свои навыки чтения и письма, вы можете сохранить то, что вам нужно. Конечно, мой уровень ограничен, поэтому, пожалуйста, поправьте меня, если у меня есть какие-то ошибки. Здесь основано наNumPy\ v1.13.dev0\ Manualпереведено. срок2018/02/04

Краткое руководство по началу работы

1 Подготовка

Прежде чем вы приступите к изучению этого руководства, вы должны немного знатьPython. Если вы хотите просмотреть его, вы можете увидетьPython tutorial. Если вы хотите запустить код учебника, вы должны установить некоторое программное обеспечение, пожалуйста, обратитесь кпоследний друг.org/install.htm…

2 Базовые знания

NumPyОсновным объектом операции является однотипный многомерный массив. Это таблица, индексированная кортежем положительных целых чисел с элементами одного типа (обычно элементами являются числа). существуетNumPyизмерение называетсяaxes, axesномер называетсяrank.

Например, в3Dточка в пространстве[1, 2, 1]Являетсяrank = 1массив, потому что он имеет только одинaxes. этоaxesДлина3. В следующем примере массивrank = 2(это2измерение). Первое измерение (axes) длина2, длина второго бита3

[[ 1., 0., 0. ],
 [ 0., 1., 2. ]]

NumPyКласс массиваndarray. также называемыйarray. Было сказано, что,numpy.arrayи стандартныйPythonв библиотекеarray.arrayэто не то же самое, он может обрабатывать только одномерные массивы и обеспечивает меньшую функциональность.ndarrayВот некоторые важные свойства объектов:

ndarray.ndim

массивaxes(размер) Числовой размер. существуетPythonРазмер среднего размера может относиться кrank

ndarray.shape

Размеры массива, который представляет собой кортеж размера каждого измерения. дляnРядmМатрица столбцов.shapeда(n, m). Зависит отshapeДлина кортежа даетrankили размерndim.

ndarray.size

сумма количества элементов массива, равнаяshapeПроизведение чисел кортежа.

ndarray.dtype

Объект, описывающий тип элемента в массиве. Это стандартPythonВведите, чтобы создать и указать тип. Кроме того,NumPyОн также предоставляет свой собственный тип:numpy.int32,numpy.int16,numpy.float64...

ndarray.itemsize

Количество байтов, занимаемых каждым элементом массива. Например,float64изitemsizeда8 ( = 64/8bit),complex32изitemsizeда4 ( = 32/8bit). это иndarray.dtype.itemsizeравны.

ndarray.data

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

2.1 Пример

>>> import numpy as np
>>> a = np.arange(15).reshape(3, 5)
>>> a
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])
>>> a.shape
(3, 5)
>>> a.ndim
2
>>> a.dtype.name
'int64'
>>> a.itemsize
8
>>> a.size
15
>>> type(a)
<type 'numpy.ndarray'>
>>> b = np.array([6, 7, 8])
>>> b
array([6, 7, 8])
>>> type(b)
<type 'numpy.ndarray'>

2.2 Создание массива

Здесь есть несколько способов создать массив.

Например, вы можете использоватьarrayфункция от обычногоPythonСписок или кортеж для создания массива. Созданный тип массива выводится из элементов в исходной последовательности.

>>> import numpy as np
>>> a = np.array([2,3,4])
>>> a
array([2, 3, 4])
>>> a.dtype
dtype('int64')
>>> b = np.array([1.2, 3.5, 5.1])
>>> b.dtype
dtype('float64')

Распространенная ошибка — называтьarrayпереданные аргументы представляют собой несколько чисел, а не один список чисел.

>>> a = np.array(1,2,3,4)    # WRONG
>>> a = np.array([1,2,3,4])  # RIGHT

arrayПреобразование последовательности в многомерный массив

>>> b = np.array([(1.5,2,3), (4,5,6)])
>>> b
array([[ 1.5,  2. ,  3. ],
       [ 4. ,  5. ,  6. ]])

Тип массива также можно указать во время создания:

>>> c = np.array( [ [1,2], [3,4] ], dtype=complex )
>>> c
array([[ 1.+0.j,  2.+0.j],
       [ 3.+0.j,  4.+0.j]])

Обычно мы все знаем размер массива, не зная исходных данных в нем. следовательноNumPyДля создания массивов предусмотрено несколько функций с заполнителями. Это минимизирует затраты на добавление массива, что является ресурсоемкой операцией.

zerosФункция создает все0массив ,onesсоздание функции это все1массив ,emptyСоздайте случайный массив. Тип создаваемого массива по умолчанию:float64.

>>> np.zeros( (3,4) )
array([[ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.]])
>>> np.ones( (2,3,4), dtype=np.int16 )                # dtype can also be specified
array([[[ 1, 1, 1, 1],
        [ 1, 1, 1, 1],
        [ 1, 1, 1, 1]],
       [[ 1, 1, 1, 1],
        [ 1, 1, 1, 1],
        [ 1, 1, 1, 1]]], dtype=int16)
>>> np.empty( (2,3) )                                 # uninitialized, output may vary
array([[  3.73603959e-262,   6.02658058e-154,   6.55490914e-260],
       [  5.30498948e-313,   3.14673309e-307,   1.00000000e+000]])

Чтобы создать последовательность чисел,NumPyобеспечивает иrangeАналогичная функция, которая возвращает массив вместо списка.

>>> np.arange( 10, 30, 5 )
array([10, 15, 20, 25])
>>> np.arange( 0, 2, 0.3 )                 # it accepts float arguments
array([ 0. ,  0.3,  0.6,  0.9,  1.2,  1.5,  1.8])

когдаarangeАргументы представляют собой числа с плавающей запятой, и из-за ограниченной точности числа с плавающей запятой обычно невозможно предсказать количество полученных элементов. По этой причине обычно выбирают лучшую функциюlinspace, который принимает в качестве аргумента количество нужных нам элементов вместо шага.

>>> from numpy import pi
>>> np.linspace( 0, 2, 9 )                 # 9 numbers from 0 to 2
array([ 0.  ,  0.25,  0.5 ,  0.75,  1.  ,  1.25,  1.5 ,  1.75,  2.  ])
>>> x = np.linspace( 0, 2*pi, 100 )        # useful to evaluate function at lots of points
>>> f = np.sin(x)
Ссылаться на

array, zeros, zeros_like, ones, ones_like, empty, empty_like, arange, linspace, numpy.random.rand, numpy.random.randn, fromfunction, fromfile

2.3 Печать массива

Когда вы печатаете массив,NumPyОтображается как вложенный список, но со следующей компоновкой:

  • последнийaxisпечатать слева направо,
  • Предпоследние печатаются сверху вниз,
  • Остальные также печатаются сверху вниз, при этом каждый срез отделяется пустой строкой.
>>> a = np.arange(6)                         # 1d array
>>> print(a)
[0 1 2 3 4 5]
>>>
>>> b = np.arange(12).reshape(4,3)           # 2d array
>>> print(b)
[[ 0  1  2]
 [ 3  4  5]
 [ 6  7  8]
 [ 9 10 11]]
>>>
>>> c = np.arange(24).reshape(2,3,4)         # 3d array
>>> print(c)
[[[ 0  1  2  3]
  [ 4  5  6  7]
  [ 8  9 10 11]]
 [[12 13 14 15]
  [16 17 18 19]
  [20 21 22 23]]]

Ссылаться нанижеполучить большеreshapeДетали.

Если массив слишком велик для печати, тоNumPyДанные в средних углах, предназначенных только для печати, автоматически игнорируются.

>>> print(np.arange(10000))
[   0    1    2 ..., 9997 9998 9999]
>>>
>>> print(np.arange(10000).reshape(100,100))
[[   0    1    2 ...,   97   98   99]
 [ 100  101  102 ...,  197  198  199]
 [ 200  201  202 ...,  297  298  299]
 ...,
 [9700 9701 9702 ..., 9797 9798 9799]
 [9800 9801 9802 ..., 9897 9898 9899]
 [9900 9901 9902 ..., 9997 9998 9999]]

Чтобы отменить это поведение, принудительноNumPyЧтобы распечатать весь массив, вы можете сделать это с помощьюset_printoptionsИзмените параметры печати.

>>> np.set_printoptions(threshold='nan')

2.4 Основные операции

К каждому элементу применяются арифметические операции над массивами. и создайте новый массив, заполненный результатами.

>>> a = np.array( [20,30,40,50] )
>>> b = np.arange( 4 )
>>> b
array([0, 1, 2, 3])
>>> c = a-b
>>> c
array([20, 29, 38, 47])
>>> b**2
array([0, 1, 4, 9])
>>> 10*np.sin(a)
array([ 9.12945251, -9.88031624,  7.4511316 , -2.62374854])
>>> a<35
array([ True, True, False, False], dtype=bool)

существуетNumPyмассив*Операции не похожи на другие матричные языки. умножение матриц черезdotфункция имитации.

>>> A = np.array( [[1,1],
...             [0,1]] )
>>> B = np.array( [[2,0],
...             [3,4]] )
>>> A*B                         # elementwise product
array([[2, 0],
       [0, 4]])
>>> A.dot(B)                    # matrix product
array([[5, 4],
       [3, 4]])
>>> np.dot(A, B)                # another matrix product
array([[5, 4],
       [3, 4]])

считать+=и*=Операции и тому подобное изменяют исходный массив напрямую, не создавая новый массив.

>>> a = np.ones((2,3), dtype=int)
>>> b = np.random.random((2,3))
>>> a *= 3
>>> a
array([[3, 3, 3],
       [3, 3, 3]])
>>> b += a
>>> b
array([[ 3.417022  ,  3.72032449,  3.00011437],
       [ 3.30233257,  3.14675589,  3.09233859]])
>>> a += b                  # b is not automatically converted to integer type
Traceback (most recent call last):
  ...
TypeError: Cannot cast ufunc add output from dtype('float64') to dtype('int64') with casting rule 'same_kind'

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

>>> a = np.ones(3, dtype=np.int32)
>>> b = np.linspace(0,pi,3)
>>> b.dtype.name
'float64'
>>> c = a+b
>>> c
array([ 1.        ,  2.57079633,  4.14159265])
>>> c.dtype.name
'float64'
>>> d = np.exp(c*1j)
>>> d
array([ 0.54030231+0.84147098j, -0.84147098+0.54030231j,
       -0.54030231-0.84147098j])
>>> d.dtype.name
'complex128'

Многие унарные операции, такие как суммирование всех элементов массива, выполняются какndarrayреализуется методами класса.

>>> a = np.random.random((2,3))
>>> a
array([[ 0.18626021,  0.34556073,  0.39676747],
       [ 0.53881673,  0.41919451,  0.6852195 ]])
>>> a.sum()
2.5718191614547998
>>> a.min()
0.1862602113776709
>>> a.max()
0.6852195003967595

По умолчанию, несмотря на то, что эти операции применяются к списку чисел, его форму можно игнорировать. В то время, указавaxisПараметры могут применять операцию к определенной части массиваaxis.

>>> b = np.arange(12).reshape(3,4)
>>> b
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>>
>>> b.sum(axis=0)                            # sum of each column
array([12, 15, 18, 21])
>>>
>>> b.min(axis=1)                            # min of each row
array([0, 4, 8])
>>>
>>> b.cumsum(axis=1)                         # cumulative sum along each row
array([[ 0,  1,  3,  6],
       [ 4,  9, 15, 22],
       [ 8, 17, 27, 38]])

2.5 Общие функции

NumPyПредоставляет множество математических функций, таких какsin,cos,exp. Они называются «универсальными функциями» (ufunc). В NumPy\) эти функции работают с числами массива, создавая массив в качестве вывода.

>>> B = np.arange(3)
>>> B
array([0, 1, 2])
>>> np.exp(B)
array([ 1.        ,  2.71828183,  7.3890561 ])
>>> np.sqrt(B)
array([ 0.        ,  1.        ,  1.41421356])
>>> C = np.array([2., -1., 4.])
>>> np.add(B, C)
array([ 2.,  0.,  6.])
Ссылаться на

all, any, apply_along_axis, argmax, argmin, argsort, average, bincount, ceil, clip, conj, corrcoef, cov, cross, cumprod, cumsum, diff, dot, floor, inner, inv, lexsort, max, maximum, mean, median, min, minimum, nonzero, outer, prod, re, round, sort, std, sum, trace, transpose, var, vdot, vectorize, where

2.6 Индексирование, нарезка и повторение

Одномерные массивы можно индексировать, нарезать и повторять, каксписокКак и любая другая последовательность Python.

>>> a = np.arange(10)**3
>>> a
array([  0,   1,   8,  27,  64, 125, 216, 343, 512, 729])
>>> a[2]
8
>>> a[2:5]
array([ 8, 27, 64])
>>> a[:6:2] = -1000    # equivalent to a[0:6:2] = -1000; from start to position 6, exclusive, set every 2nd element to -1000
>>> a
array([-1000,     1, -1000,    27, -1000,   125,   216,   343,   512,   729])
>>> a[ : :-1]                                 # reversed a
array([  729,   512,   343,   216,   125, -1000,    27, -1000,     1, -1000])
>>> for i in a:
...     print(i**(1/3.))
...
nan
1.0
nan
3.0
nan
5.0
6.0
7.0
8.0
9.0

многомерный массив для каждогоaxisЕсть индекс, и эти индексы разделены запятыми.

>>> def f(x,y):
...     return 10*x+y
...
>>> b = np.fromfunction(f,(5,4),dtype=int)
>>> b
array([[ 0,  1,  2,  3],
       [10, 11, 12, 13],
       [20, 21, 22, 23],
       [30, 31, 32, 33],
       [40, 41, 42, 43]])
>>> b[2,3]
23
>>> b[0:5, 1]                       # each row in the second column of b
array([ 1, 11, 21, 31, 41])
>>> b[ : ,1]                        # equivalent to the previous example
array([ 1, 11, 21, 31, 41])
>>> b[1:3, : ]                      # each column in the second and third row of b
array([[10, 11, 12, 13],
       [20, 21, 22, 23]])

Когда указанный индекс меньшеaxisчисло, отсутствующие индексы считаются полными срезами.

>>> b[-1]                                  # the last row. Equivalent to b[-1,:]
array([40, 41, 42, 43])

b[i]выражение в скобкахiЕго можно использовать намного позже:указать другоеaxisпример.NumPyДопускаются также три точки вместоb[i, ...]

Эти три пункта (...) представляет двоеточие во многих кортежах с полным индексом. Например,xизrank = 5имеют:

  • x[1, 2, ...] = x[1, 2, :, :, :]
  • x[..., 3] = x[:, :, :, :, 3]
  • x[4, ..., 5, :] = x[4, :, :, 5, :]
>>> c = np.array( [[[  0,  1,  2],               # a 3D array (two stacked 2D arrays)
...                 [ 10, 12, 13]],
...                [[100,101,102],
...                 [110,112,113]]])
>>> c.shape
(2, 2, 3)
>>> c[1,...]                                   # same as c[1,:,:] or c[1]
array([[100, 101, 102],
       [110, 112, 113]])
>>> c[...,2]                                   # same as c[:,:,2]
array([[  2,  13],
       [102, 113]])

Итерация по многомерному массиву является первымaxisнепрерывный.

>>> for row in b:
...     print(row)
...
[0 1 2 3]
[10 11 12 13]
[20 21 22 23]
[30 31 32 33]
[40 41 42 43]

Однако, если вы хотите имитировать операции над каждым элементом массива, вы можете использоватьflatсобственность, этоiterator, чтобы перебрать каждый элемент в массиве.

>>> for element in b.flat:
...     print(element)
...
0
1
2
3
10
11
12
13
20
21
22
23
30
31
32
33
40
41
42
43
Ссылаться на

Indexing, Indexing (reference), newaxis, ndenumerate, indices

3 Управление фигурами

3.1 Изменение формы массива

Форма каждого массива передается через каждыйaxisколичество элементов в . (Фактически определяется количество элементов в каждом измерении)

>>> a = np.floor(10*np.random.random((3,4)))
>>> a
array([[ 2.,  8.,  0.,  6.],
       [ 4.,  5.,  1.,  1.],
       [ 8.,  9.,  3.,  6.]])
>>> a.shape
(3, 4)

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

>>> a.ravel()  # returns the array, flattened
array([ 2.,  8.,  0.,  6.,  4.,  5.,  1.,  1.,  8.,  9.,  3.,  6.])
>>> a.reshape(6,2)  # returns the array with a modified shape
array([[ 2.,  8.],
       [ 0.,  6.],
       [ 4.,  5.],
       [ 1.,  1.],
       [ 8.,  9.],
       [ 3.,  6.]])
>>> a.T  # returns the array, transposed
array([[ 2.,  4.,  8.],
       [ 8.,  5.,  9.],
       [ 0.,  1.,  3.],
       [ 6.,  1.,  6.]])
>>> a.T.shape
(4, 3)
>>> a.shape
(3, 4)

ravel()Позиция каждого элемента в функции обычно соответствует «стилю C», то есть самый правый индекс изменяется быстрее всего. поэтому элементa[0, 0]Следующие элементыa[0, 1]. Если массив имеет любую другую форму, массив также рассматривается как «C-стиль».NumPyМассивы обычно создаются в соответствии с этим, поэтому используйтеravel()Функция не нуждается в копировании, но если массив получен путем нарезки из другого массива или каким-либо другим необычным способом, она делает это. функцияravel()иreshape()Также может быть указан с необязательными параметрамиFORTRAN-styleМассивы, в этом стиле самый левый индекс меняется быстрее всего.

reshapeфункция возвращает измененную форму, аndarray.resizeметод напрямую изменяет сам массив.

>>> a
array([[ 2.,  8.,  0.,  6.],
       [ 4.,  5.,  1.,  1.],
       [ 8.,  9.,  3.,  6.]])
>>> a.resize((2,6))
>>> a
array([[ 2.,  8.,  0.,  6.,  4.,  5.],
       [ 1.,  1.,  8.,  9.,  3.,  6.]])

Если измерение дает-1в качестве параметра, то другие размеры будут рассчитаны автоматически.

>>> a.reshape(3,-1)
array([[ 2.,  8.,  0.,  6.],
       [ 4.,  5.,  1.,  1.],
       [ 8.,  9.,  3.,  6.]])
Ссылаться на

ndarray.shape, reshape, resize, ravel

3.2 Комбинации разных массивов

Массивы можно передавать через разныеaxesкомбинировать.

>>> a = np.floor(10*np.random.random((2,2)))
>>> a
array([[ 8.,  8.],
       [ 0.,  0.]])
>>> b = np.floor(10*np.random.random((2,2)))
>>> b
array([[ 1.,  8.],
       [ 0.,  4.]])
>>> np.vstack((a,b))
array([[ 8.,  8.],
       [ 0.,  0.],
       [ 1.,  8.],
       [ 0.,  4.]])
>>> np.hstack((a,b))
array([[ 8.,  8.,  1.,  8.],
       [ 0.,  0.,  0.,  4.]])

column_stackфункция может быть1Dмассив как2DСтолбцы массива. тогда и только тогда, когда массив1Dкогда он равенvstack

>>> from numpy import newaxis
>>> np.column_stack((a,b))   # With 2D arrays
array([[ 8.,  8.,  1.,  8.],
       [ 0.,  0.,  0.,  4.]])
>>> a = np.array([4.,2.])
>>> b = np.array([2.,8.])
>>> a[:,newaxis]  # This allows to have a 2D columns vector
array([[ 4.],
       [ 2.]])
>>> np.column_stack((a[:,newaxis],b[:,newaxis]))
array([[ 4.,  2.],
       [ 2.,  8.]])
>>> np.vstack((a[:,newaxis],b[:,newaxis])) # The behavior of vstack is different
array([[ 4.],
       [ 2.],
       [ 2.],
       [ 8.]])

Для массивов с более чем двумя измерениямиhstackпоследует за вторымaxisнакопление,vstackвдоль первогоaxesнакопление,concatenateПозволяет необязательный параметр выбрать, какой из нихaxisПроизошла операция подключения.

намекать

В сложных ситуациях,r_иc_Для прохождения по а.axisПолезно для укладки чисел для создания массивов. Они позволяют использовать обозначение диапазона (":")

>>> np.r_[1:4,0,4]
array([1, 2, 3, 0, 4])

При использовании массива в качестве параметраr_иc_Поведение по умолчанию иvstackиhstackпохожи, но они позволяют указывать необязательные аргументыaxisподключить.

Ссылаться на

hstack,vstack,column_stack,concatenate,c_,r_

3.3 Разделите массив на несколько небольших массивов

использоватьhsplit, вы можете следить за его уровнемaxisРазбиение, которое можно вернуть, указав форму массива, а также какой столбец следует разбить:

>>> a = np.floor(10*np.random.random((2,12)))
>>> a
array([[ 9.,  5.,  6.,  3.,  6.,  8.,  0.,  7.,  9.,  7.,  2.,  7.],
       [ 1.,  4.,  9.,  2.,  2.,  1.,  0.,  6.,  2.,  2.,  4.,  0.]])
>>> np.hsplit(a,3)   # Split a into 3
[array([[ 9.,  5.,  6.,  3.],
       [ 1.,  4.,  9.,  2.]]), array([[ 6.,  8.,  0.,  7.],
       [ 2.,  1.,  0.,  6.]]), array([[ 9.,  7.,  2.,  7.],
       [ 2.,  2.,  4.,  0.]])]
>>> np.hsplit(a,(3,4))   # Split a after the third and the fourth column
[array([[ 9.,  5.,  6.],
       [ 1.,  4.,  9.]]), array([[ 3.],
       [ 2.]]), array([[ 6.,  8.,  0.,  7.,  9.,  7.,  2.,  7.],
       [ 2.,  1.,  0.,  6.,  2.,  2.,  4.,  0.]])]

vplitпо вертикалиaxisсегментация,array_splitразрешено, указав, какиеaxisделить.

4 копии и представления

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

4.1 Нет копии

Простое присваивание не копирует никакие объекты массива и их данные.

>>> a = np.arange(12)
>>> b = a            # no new object is created
>>> b is a           # a and b are two names for the same ndarray object
True
>>> b.shape = 3,4    # changes the shape of a
>>> a.shape
(3, 4)

PythonПередавайте изменяемые объекты как ссылки, чтобы вызовы функций не создавали копии.

>>> def f(x):
...     print(id(x))
...
>>> id(a)                           # id is a unique identifier of an object
148293216
>>> f(a)
148293216

4.2 Просмотр или поверхностное копирование

Одни и те же данные могут использоваться разными объектами массива.viewметод создает новый объект массива с теми же данными. PS: Вот View (просмотр?) Я не знаю, как это хорошо понять, так что держите.

>>> c = a.view()
>>> c is a
False
>>> c.base is a                        # c is a view of the data owned by a
True
>>> c.flags.owndata
False
>>>
>>> c.shape = 2,6                      # a's shape doesn't change
>>> a.shape
(3, 4)
>>> c[0,4] = 1234                      # a's data changes
>>> a
array([[   0,    1,    2,    3],
       [1234,    5,    6,    7],
       [   8,    9,   10,   11]])

нарезанный массив возвращаетview:

>>> s = a[ : , 1:3]     # spaces added for clarity; could also be written "s = a[:,1:3]"
>>> s[:] = 10           # s[:] is a view of s. Note the difference between s=10 and s[:]=10
>>> a
array([[   0,   10,   10,    3],
       [1234,   10,   10,    7],
       [   8,   10,   10,   11]])

4.3 Глубокое копирование

copyМетод полностью копирует массив.

>>> d = a.copy()                          # a new array object with new data is created
>>> d is a
False
>>> d.base is a                           # d doesn't share anything with a
False
>>> d[0,0] = 9999
>>> a
array([[   0,   10,   10,    3],
       [1234,   10,   10,    7],
       [   8,   10,   10,   11]])

4.4 Обзор функций и методов

Вот несколько полезных списков, отсортированных по категориямNumPyфункции и методы. Чтобы увидеть полный список, нажмите здесьRoutines

коллекция массивов

arange, array, copy, empty, empty_like, eye, fromfile, fromfunction, identity, linspace, logspace, mgrid, ogrid, ones, ones_like, r, zeros, zeros_like

конвертировать

ndarray.astype, atleast_1d, atleast_2d, atleast_3d, mat

действовать

array_split, column_stack, concatenate, diagonal, dsplit, dstack, hsplit, hstack, ndarray.item, newaxis, ravel, repeat, reshape, resize, squeeze, swapaxes, take, transpose, vsplit, vstack

сомневаться

all, any, nonzero, where

Сортировать

argmax, argmin, argsort, max, min, ptp, searchsorted, sort

операция

choose, compress, cumprod, cumsum, inner, ndarray.fill, imag, prod, put, putmask, real, sum

Основная статистика

cov, mean, std, var

Базовая линейная алгебра

cross, dot, outer, linalg.svd, vdot

5 Less Basic

5.1 Правила трансляции

Вещание позволяет универсальным функциям осмысленно обрабатывать входные данные различной формы. Первое правило вещания состоит в том, что если все входные массивы не имеют одинакового количества измерений, то оно будет повторяться с1для добавления к меньшим фигурам массива, пока все массивы не будут иметь одинаковый размерный номер. Второе правило вещания состоит в том, чтобы гарантировать, что по определенному измерению размер1Размер массива равен максимальному измерению по этому измерению, при условии, что значения элементов массива одинаковы по размерам широковещательного массива. После применения широковещательных правил размеры всех массивов не обязательно должны совпадать. Более подробную информацию можно найти наBroadcasting.

6 необычных трюков с индексированием и индексированием

NumPyобеспечивает соотношениеPythonПоследовательность больше возможностей индексации. Помимо индексации целыми числами и срезами, как мы видели ранее, массивы можно индексировать целочисленными массивами и булевыми массивами.

6.1 Индексирование с помощью индексированных массивов

>>> a = np.arange(12)**2                       # the first 12 square numbers
>>> i = np.array( [ 1,1,3,8,5 ] )              # an array of indices
>>> a[i]                                       # the elements of a at the positions i
array([ 1,  1,  9, 64, 25])
>>>
>>> j = np.array( [ [ 3, 4], [ 9, 7 ] ] )      # a bidimensional array of indices
>>> a[j]                                       # the same shape as j
array([[ 9, 16],
       [81, 49]])

когда массивaявляется многомерным, один массив указывает на массивaпервое измерение . В следующем примере показано такое поведение с использованием палитры для преобразования изображения этикетки в цветное изображение.

>>> palette = np.array( [ [0,0,0],                # black
...                       [255,0,0],              # red
...                       [0,255,0],              # green
...                       [0,0,255],              # blue
...                       [255,255,255] ] )       # white
>>> image = np.array( [ [ 0, 1, 2, 0 ],           # each value corresponds to a color in the palette
...                     [ 0, 3, 4, 0 ]  ] )
>>> palette[image]                            # the (2,4,3) color image
array([[[  0,   0,   0],
        [255,   0,   0],
        [  0, 255,   0],
        [  0,   0,   0]],
       [[  0,   0,   0],
        [  0,   0, 255],
        [255, 255, 255],
        [  0,   0,   0]]])

Мы можем индексировать более одного измерения. Форма индекса каждого измерения массива должна быть одинаковой.

>>> a = np.arange(12).reshape(3,4)
>>> a
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>> i = np.array( [ [0,1],                        # indices for the first dim of a
...                 [1,2] ] )
>>> j = np.array( [ [2,1],                        # indices for the second dim
...                 [3,3] ] )
>>>
>>> a[i,j]                                     # i and j must have equal shape
array([[ 2,  5],
       [ 7, 11]])
>>>
>>> a[i,2]
array([[ 2,  6],
       [ 6, 10]])
>>>
>>> a[:,j]                                     # i.e., a[ : , j]
array([[[ 2,  1],
        [ 3,  3]],
       [[ 6,  5],
        [ 7,  7]],
       [[10,  9],
        [11, 11]]])

Конечно, мы можем поставитьi, jПоместите в последовательность и проиндексируйте в списке.

>>> l = [i,j]
>>> a[l]                                       # equivalent to a[i,j]
array([[ 2,  5],
       [ 7, 11]])

Однако мы можем непосредственноi,jв массив, так как этот массив будет интерпретироваться какaИндекс первого измерения.

>>> s = np.array( [i,j] )
>>> a[s]                                       # not what we want
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
IndexError: index (3) out of range (0<=index<=2) in dimension 0
>>>
>>> a[tuple(s)]                                # same as a[i,j]
array([[ 2,  5],
       [ 7, 11]])

Другим распространенным индексом массива является запрос максимального значения ряда, зависящего от времени.

>>> time = np.linspace(20, 145, 5)                 # time scale
>>> data = np.sin(np.arange(20)).reshape(5,4)      # 4 time-dependent series
>>> time
array([  20.  ,   51.25,   82.5 ,  113.75,  145.  ])
>>> data
array([[ 0.        ,  0.84147098,  0.90929743,  0.14112001],
       [-0.7568025 , -0.95892427, -0.2794155 ,  0.6569866 ],
       [ 0.98935825,  0.41211849, -0.54402111, -0.99999021],
       [-0.53657292,  0.42016704,  0.99060736,  0.65028784],
       [-0.28790332, -0.96139749, -0.75098725,  0.14987721]])
>>>
>>> ind = data.argmax(axis=0)                   # index of the maxima for each series
>>> ind
array([2, 0, 3, 1])
>>>
>>> time_max = time[ ind]                       # times corresponding to the maxima
>>>
>>> data_max = data[ind, xrange(data.shape[1])] # => data[ind[0],0], data[ind[1],1]...
>>>
>>> time_max
array([  82.5 ,   20.  ,  113.75,   51.25])
>>> data_max
array([ 0.98935825,  0.84147098,  0.99060736,  0.6569866 ])
>>>
>>> np.all(data_max == data.max(axis=0))
True

Вы также можете присваивать значения массивам, используя индексы массива:

>>> a = np.arange(5)
>>> a
array([0, 1, 2, 3, 4])
>>> a[[1,3,4]] = 0
>>> a
array([0, 0, 2, 0, 0])

Однако, когда ваш индекс списка содержит дубликаты, это присвоение произойдет несколько раз, сохраняя последнее значение.

>>> a = np.arange(5)
>>> a[[0,0,2]]=[1,2,3]
>>> a
array([2, 1, 3, 3, 4])

Это достаточно разумно, но если вы хотите использоватьPythonиз+=Будьте осторожны при структурировании, это может быть не то, что вы ожидаете:

>>> a = np.arange(5)
>>> a[[0,0,2]]+=1
>>> a
array([1, 1, 3, 3, 4])

Несмотря на то0появляется в списке дважды, первый0элементы увеличиваются только один раз. Это потому чтоPythonПриравнивает "a+=1" к "a=a+1".

6.2 Индексирование с помощью логических массивов

Когда мы индексируем массив массивом целых чисел, мы предоставляем список индексов для выбора. Метод с булевым индексированием бесполезен, мы явно выбираем, какой из массивов нам нужен, а какой нет. Самый естественный способ думать об этом — использовать логическое индексирование с логическим массивом той же формы, что и исходный массив.

>>> a = np.arange(12).reshape(3,4)
>>> b = a > 4
>>> b                                          # b is a boolean with a's shape
array([[False, False, False, False],
       [False,  True,  True,  True],
       [ True,  True,  True,  True]], dtype=bool)
>>> a[b]                                       # 1d array with the selected elements
array([ 5,  6,  7,  8,  9, 10, 11])

Это свойство очень полезно при копировании.

>>> a[b] = 0                                   # All elements of 'a' higher than 4 become 0
>>> a
array([[0, 1, 2, 3],
       [4, 0, 0, 0],
       [0, 0, 0, 0]])

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

>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>> def mandelbrot( h,w, maxit=20 ):
...     """Returns an image of the Mandelbrot fractal of size (h,w)."""
...     y,x = np.ogrid[ -1.4:1.4:h*1j, -2:0.8:w*1j ]
...     c = x+y*1j
...     z = c
...     divtime = maxit + np.zeros(z.shape, dtype=int)
...
...     for i in range(maxit):
...         z = z**2 + c
...         diverge = z*np.conj(z) > 2**2            # who is diverging
...         div_now = diverge & (divtime==maxit)  # who is diverging now
...         divtime[div_now] = i                  # note when
...         z[diverge] = 2                        # avoid diverging too much
...
...     return divtime
>>> plt.imshow(mandelbrot(400,400))
>>> plt.show()
import numpy as np
import matplotlib.pyplot as plt

def mandelbrot(h, w, maxit=20):
    y, x = np.ogrid[-1.4:1.4:h * 1j, -2:0.8:w * 1j]
    c = x + y * 1j
    z = c
    divtime = maxit + np.zeros(z.shape, dtype=int)
    for i in range(maxit):
        z = z ** 2 + c
        diverge = z * np.conj(z) > 2 ** 2  # who is diverging
        div_now = diverge & (divtime == maxit)  # who is diverging now
        divtime[div_now] = i  # note when
        z[diverge] = 2  # avoid diverging too much
    return divtime

plt.imshow(mandelbrot(400, 400))
plt.show()

Второй метод с булевой индексацией больше похож на целочисленную индексацию, для каждого измерения массива мы даем1Dлогический массив для выбора нужного фрагмента.

>>> a = np.arange(12).reshape(3,4)
>>> b1 = np.array([False,True,True])             # first dim selection
>>> b2 = np.array([True,False,True,False])       # second dim selection
>>>
>>> a[b1,:]                                   # selecting rows
array([[ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>>
>>> a[b1]                                     # same thing
array([[ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>>
>>> a[:,b2]                                   # selecting columns
array([[ 0,  2],
       [ 4,  6],
       [ 8, 10]])
>>>
>>> a[b1,b2]                                  # a weird thing to do
array([ 4, 10])

Пожалуйста, обрати внимание,1DДлина логического массива должна соответствовать измерению, которое вы нарезаете (илиaxis) той же длины. В предыдущем примереb1длина3(aколичество строк) из1-rankмножество,b2(длина $4$) — подходящий деиндексaсекундаrank(Список).

6.3 Функция ix_()

ix_Различные векторы можно комбинировать, чтобы получить для каждогоn-upletрезультат. Например, если вы хотитеa, b, cполучить тройки из вектора, чтобы вычислить всеa+b*c:

>>> a = np.array([2,3,4,5])
>>> b = np.array([8,5,4])
>>> c = np.array([5,4,6,8,3])
>>> ax,bx,cx = np.ix_(a,b,c)
>>> ax
array([[[2]],
       [[3]],
       [[4]],
       [[5]]])
>>> bx
array([[[8],
        [5],
        [4]]])
>>> cx
array([[[5, 4, 6, 8, 3]]])
>>> ax.shape, bx.shape, cx.shape
((4, 1, 1), (1, 3, 1), (1, 1, 5))
>>> result = ax+bx*cx
>>> result
array([[[42, 34, 50, 66, 26],
        [27, 22, 32, 42, 17],
        [22, 18, 26, 34, 14]],
       [[43, 35, 51, 67, 27],
        [28, 23, 33, 43, 18],
        [23, 19, 27, 35, 15]],
       [[44, 36, 52, 68, 28],
        [29, 24, 34, 44, 19],
        [24, 20, 28, 36, 16]],
       [[45, 37, 53, 69, 29],
        [30, 25, 35, 45, 20],
        [25, 21, 29, 37, 17]]])
>>> result[3,2,4]
17
>>> a[3]+b[2]*c[4]
17

Вы также можете сделать это следующим образом:

>>> def ufunc_reduce(ufct, *vectors):
...    vs = np.ix_(*vectors)
...    r = ufct.identity
...    for v in vs:
...        r = ufct(r,v)
...    return r

Затем используйте так:

>>> ufunc_reduce(np.add,a,b,c)
array([[[15, 14, 16, 18, 13],
        [12, 11, 13, 15, 10],
        [11, 10, 12, 14,  9]],
       [[16, 15, 17, 19, 14],
        [13, 12, 14, 16, 11],
        [12, 11, 13, 15, 10]],
       [[17, 16, 18, 20, 15],
        [14, 13, 15, 17, 12],
        [13, 12, 14, 16, 11]],
       [[18, 17, 19, 21, 16],
        [15, 14, 16, 18, 13],
        [14, 13, 15, 17, 12]]])

Эта версия больше, чем обычнаяufunc.reduceК счастью, он используетBroadcasting RulesПравило, позволяющее избежать создания массива размером, равно количеству векторов, умноженному на результат.

6.4 Использование строковых индексов

Ссылаться наStructured arrays

7 Линейная алгебра

Работа продолжается, и базовая линейная алгебра покрыта.

7.1 Простые операции с массивами

СмотретьNumPyв папкеlinalg.pyдокумент, чтобы узнать больше.

>>> import numpy as np
>>> a = np.array([[1.0, 2.0], [3.0, 4.0]])
>>> print(a)
[[ 1.  2.]
 [ 3.  4.]]

>>> a.transpose()
array([[ 1.,  3.],
       [ 2.,  4.]])

>>> np.linalg.inv(a)
array([[-2. ,  1. ],
       [ 1.5, -0.5]])

>>> u = np.eye(2) # unit 2x2 matrix; "eye" represents "I"
>>> u
array([[ 1.,  0.],
       [ 0.,  1.]])
>>> j = np.array([[0.0, -1.0], [1.0, 0.0]])

>>> np.dot (j, j) # matrix product
array([[-1.,  0.],
       [ 0., -1.]])

>>> np.trace(u)  # trace
2.0

>>> y = np.array([[5.], [7.]])
>>> np.linalg.solve(a, y)
array([[-3.],
       [ 4.]])

>>> np.linalg.eig(j)
(array([ 0.+1.j,  0.-1.j]), array([[ 0.70710678+0.j        ,  0.70710678-0.j        ],
       [ 0.00000000-0.70710678j,  0.00000000+0.70710678j]]))
Parameters:
    square matrix
Returns
    The eigenvalues, each repeated according to its multiplicity.
    The normalized (unit "length") eigenvectors, such that the
    column ``v[:,i]`` is the eigenvector corresponding to the
    eigenvalue ``w[i]`` .

8 советов и подсказок

Здесь мы даем несколько полезных советов.

8.1 «Автоформирование»

Чтобы изменить размерность массива, можно опустить параметр, размер которого можно вычислить автоматически.

>>> a = np.arange(30)
>>> a.shape = 2,-1,3  # -1 means "whatever is needed"
>>> a.shape
(2, 5, 3)
>>> a
array([[[ 0,  1,  2],
        [ 3,  4,  5],
        [ 6,  7,  8],
        [ 9, 10, 11],
        [12, 13, 14]],
       [[15, 16, 17],
        [18, 19, 20],
        [21, 22, 23],
        [24, 25, 26],
        [27, 28, 29]]])

8.2 Векторное наложение

Как мы строим вектор-строку из вектора-строки того же размера2Dмножество? существуетMATLABдовольно просто: еслиxиyдва вектора одинаковой длины, вам просто нужно поставитьm=[x;y]. существуетNumPy, через функциюcolumn_stack,dstack,hstackиvstackреализации, это зависит от накладываемого измерения. Например:

x = np.arange(0,10,2)                     # x=([0,2,4,6,8])
y = np.arange(5)                          # y=([0,1,2,3,4])
m = np.vstack([x,y])                      # m=([[0,2,4,6,8],
                                          #     [0,1,2,3,4]])
xy = np.hstack([x,y])                     # xy =([0,2,4,6,8,0,1,2,3,4])

Логика этих функций странная, когда измерений больше двух.

Ссылаться на

NumPy for Matlab users

8.3 Гистограмма

NumPyизhistogramфункция, применяемая к массиву, возвращает пару векторов: гистограмму массива иbinsвектор. Остерегаться:matplotlibСуществует также функция построения гистограмм (называемаяhist, Также вMatlab), это иNumPyВсе еще не то же самое. Основное отличиеpylab.histавтоматически рисует гистограммы, покаmatplotlibПросто сгенерируйте данные.

>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>> # Build a vector of 10000 normal deviates with variance 0.5^2 and mean 2
>>> mu, sigma = 2, 0.5
>>> v = np.random.normal(mu,sigma,10000)
>>> # Plot a normalized histogram with 50 bins
>>> plt.hist(v, bins=50, normed=1)       # matplotlib version (plot)
>>> plt.show()
import numpy as np
import matplotlib.pyplot as plt

# Build a vector of 10000 normal deviates with variance 0.5^2 and mean 2
mu, sigma = 2, 0.5
v = np.random.normal(mu, sigma, 10000)
# Plot a normalized histogram with 50 bins
plt.hist(v, bins=50, normed=1)  # matplotlib version (plot)
plt.show()

>>> # Compute the histogram with numpy and then plot it
>>> (n, bins) = np.histogram(v, bins=50, normed=True)  # NumPy version (no plot)
>>> plt.plot(.5*(bins[1:]+bins[:-1]), n)
>>> plt.show()
import numpy as np
import matplotlib.pyplot as plt

# Build a vector of 10000 normal deviates with variance 0.5^2 and mean 2
mu, sigma = 2, 0.5
v = np.random.normal(mu, sigma, 10000)
# Compute the histogram with numpy and then plot it
(n, bins) = np.histogram(v, bins=50, normed=True)  # NumPy version (no plot)
plt.plot(.5 * (bins[1:] + bins[:-1]), n)
plt.show()

9 больше чтения