Спереди написано: Изначально это было для учебы.
, смотрите официальный сайтРуководство по началу работыЯ хочу проследить за экспериментом, боюсь, что им не часто пользуются, да и я забывчивый, поэтому записал. Просто следите за переводом, вы также можете улучшить свои навыки чтения и письма, вы можете сохранить то, что вам нужно. Конечно, мой уровень ограничен, поэтому, пожалуйста, поправьте меня, если у меня есть какие-то ошибки. Здесь основано на
переведено. срок
Краткое руководство по началу работы
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()