Спереди написано: Изначально это было для учебы., смотрите официальный сайтРуководство по началу работыЯ хочу проследить за экспериментом, боюсь, что им не часто пользуются, да и я забывчивый, поэтому записал. Просто следите за переводом, вы также можете улучшить свои навыки чтения и письма, вы можете сохранить то, что вам нужно. Конечно, мой уровень ограничен, поэтому, пожалуйста, поправьте меня, если у меня есть какие-то ошибки. Здесь основано напереведено. срок
Краткое руководство по началу работы
1 Подготовка
Прежде чем вы приступите к изучению этого руководства, вы должны немного знать. Если вы хотите просмотреть его, вы можете увидетьPython tutorial. Если вы хотите запустить код учебника, вы должны установить некоторое программное обеспечение, пожалуйста, обратитесь кпоследний друг.org/install.htm…
2 Базовые знания
Основным объектом операции является однотипный многомерный массив. Это таблица, индексированная кортежем положительных целых чисел с элементами одного типа (обычно элементами являются числа). существуетизмерение называетсяaxes
, axes
номер называетсяrank
.
Например, вточка в пространствеЯвляетсяrank = 1
массив, потому что он имеет только одинaxes
. этоaxes
Длина. В следующем примере массивrank = 2
(этоизмерение). Первое измерение (axes
) длина, длина второго бита
[[ 1., 0., 0. ],
[ 0., 1., 2. ]]
Класс массиваndarray
. также называемыйarray
. Было сказано, что,numpy.array
и стандартныйв библиотекеarray.array
это не то же самое, он может обрабатывать только одномерные массивы и обеспечивает меньшую функциональность.ndarray
Вот некоторые важные свойства объектов:
ndarray.ndim
массив
axes
(размер) Числовой размер. существуетРазмер среднего размера может относиться кrank
ndarray.shape
Размеры массива, который представляет собой кортеж размера каждого измерения. дляРядМатрица столбцов.
shape
да(n, m)
. Зависит отshape
Длина кортежа даетrank
или размерndim
.
ndarray.size
сумма количества элементов массива, равная
shape
Произведение чисел кортежа.
ndarray.dtype
Объект, описывающий тип элемента в массиве. Это стандартВведите, чтобы создать и указать тип. Кроме того,Он также предоставляет свой собственный тип:
numpy.int32
,numpy.int16
,numpy.float64
...
ndarray.itemsize
Количество байтов, занимаемых каждым элементом массива. Например,
float64
изitemsize
да,complex32
изitemsize
да. это и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
функция от обычногоСписок или кортеж для создания массива. Созданный тип массива выводится из элементов в исходной последовательности.
>>> 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]])
Обычно мы все знаем размер массива, не зная исходных данных в нем. следовательноДля создания массивов предусмотрено несколько функций с заполнителями. Это минимизирует затраты на добавление массива, что является ресурсоемкой операцией.
zeros
Функция создает всемассив ,ones
создание функции это всемассив ,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]])
Чтобы создать последовательность чисел,обеспечивает и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 Печать массива
Когда вы печатаете массив,Отображается как вложенный список, но со следующей компоновкой:
- последний
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
Детали.
Если массив слишком велик для печати, тоДанные в средних углах, предназначенных только для печати, автоматически игнорируются.
>>> 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]]
Чтобы отменить это поведение, принудительноЧтобы распечатать весь массив, вы можете сделать это с помощью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)
существуетмассив*
Операции не похожи на другие матричные языки. умножение матриц через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 Общие функции
Предоставляет множество математических функций, таких как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.])
Ссылаться на
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
пример.Допускаются также три точки вместо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-стиль».Массивы обычно создаются в соответствии с этим, поэтому используйте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.]])
Если измерение даетв качестве параметра, то другие размеры будут рассчитаны автоматически.
>>> 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функция может бытьмассив какСтолбцы массива. тогда и только тогда, когда массивкогда он равен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)
Передавайте изменяемые объекты как ссылки, чтобы вызовы функций не создавали копии.
>>> 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 Обзор функций и методов
Вот несколько полезных списков, отсортированных по категориямфункции и методы. Чтобы увидеть полный список, нажмите здесьRoutines
коллекция массивов
конвертировать
действовать
сомневаться
Сортировать
операция
choose, compress, cumprod, cumsum, inner, ndarray.fill, imag, prod, put, putmask, real, sum
Основная статистика
Базовая линейная алгебра
5 Less Basic
5.1 Правила трансляции
Вещание позволяет универсальным функциям осмысленно обрабатывать входные данные различной формы. Первое правило вещания состоит в том, что если все входные массивы не имеют одинакового количества измерений, то оно будет повторяться сдля добавления к меньшим фигурам массива, пока все массивы не будут иметь одинаковый размерный номер. Второе правило вещания состоит в том, чтобы гарантировать, что по определенному измерению размерРазмер массива равен максимальному измерению по этому измерению, при условии, что значения элементов массива одинаковы по размерам широковещательного массива. После применения широковещательных правил размеры всех массивов не обязательно должны совпадать. Более подробную информацию можно найти наBroadcasting.
6 необычных трюков с индексированием и индексированием
обеспечивает соотношениеПоследовательность больше возможностей индексации. Помимо индексации целыми числами и срезами, как мы видели ранее, массивы можно индексировать целочисленными массивами и булевыми массивами.
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])
Это достаточно разумно, но если вы хотите использоватьиз+=
Будьте осторожны при структурировании, это может быть не то, что вы ожидаете:
>>> a = np.arange(5)
>>> a[[0,0,2]]+=1
>>> a
array([1, 1, 3, 3, 4])
Несмотря на топоявляется в списке дважды, первыйэлементы увеличиваются только один раз. Это потому чтоПриравнивает "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()
Второй метод с булевой индексацией больше похож на целочисленную индексацию, для каждого измерения массива мы даемлогический массив для выбора нужного фрагмента.
>>> 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])
Пожалуйста, обрати внимание,Длина логического массива должна соответствовать измерению, которое вы нарезаете (илиaxis
) той же длины. В предыдущем примереb1
длина(a
количество строк) из1-rank
множество,b2
(длина $4$) — подходящий деиндексa
секундаrank
(Список).
6.3 Функция ix_()
ix_Различные векторы можно комбинировать, чтобы получить для каждогоn-uplet
результат. Например, если вы хотитеполучить тройки из вектора, чтобы вычислить все:
>>> 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 Простые операции с массивами
Смотретьв папкедокумент, чтобы узнать больше.
>>> 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 Векторное наложение
Как мы строим вектор-строку из вектора-строки того же размерамножество? существуетдовольно просто: еслиx
иy
два вектора одинаковой длины, вам просто нужно поставитьm=[x;y]
. существует, через функцию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])
Логика этих функций странная, когда измерений больше двух.
Ссылаться на
8.3 Гистограмма
изhistogram
функция, применяемая к массиву, возвращает пару векторов: гистограмму массива иbins
вектор. Остерегаться:matplotlib
Существует также функция построения гистограмм (называемаяhist
, Также в), это иВсе еще не то же самое. Основное отличие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()