Поиск…


Вступление

N-мерные массивы или ndarrays являются основным объектом numpy, который используется для хранения элементов одного и того же типа данных. Они обеспечивают эффективную структуру данных, превосходящую обычные массивы Python.

замечания

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

Создать массив

Пустой массив

np.empty((2,3))

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

Из списка

np.array([0,1,2,3])
# Out: array([0, 1, 2, 3]) 

Создать диапазон

np.arange(4)
# Out: array([0, 1, 2, 3])

Создать нули

np.zeros((3,2))
# Out:
# array([[ 0.,  0.],
#        [ 0.,  0.],
#        [ 0.,  0.]])

Создать

np.ones((3,2))
# Out:
# array([[ 1.,  1.],
#        [ 1.,  1.],
#        [ 1.,  1.]])

Создание элементов массива с линейным интервалом

np.linspace(0,1,21)
# Out:
# array([ 0.  ,  0.05,  0.1 ,  0.15,  0.2 ,  0.25,  0.3 ,  0.35,  0.4 ,
#         0.45,  0.5 ,  0.55,  0.6 ,  0.65,  0.7 ,  0.75,  0.8 ,  0.85,
#         0.9 ,  0.95,  1.  ])

Создание элементов массива с разбиением на лог

np.logspace(-2,2,5)
# Out:
# array([  1.00000000e-02,   1.00000000e-01,   1.00000000e+00,
#          1.00000000e+01,   1.00000000e+02])

Создать массив из заданной функции

np.fromfunction(lambda i: i**2, (5,))
# Out:
# array([  0.,   1.,   4.,   9.,  16.])
np.fromfunction(lambda i,j: i**2, (3,3))
# Out:
# array([[ 0.,  0.,  0.],
#        [ 1.,  1.,  1.],
#        [ 4.,  4.,  4.]])

Операторы массива

x = np.arange(4)
x
#Out:array([0, 1, 2, 3])

скалярное добавление является элементарным

x+10
#Out: array([10, 11, 12, 13])

скалярное умножение является элементарным

x*2
#Out: array([0, 2, 4, 6])

добавление массива является элементарным

x+x
#Out: array([0, 2, 4, 6]) 

умножение массива является элементарным

x*x
#Out: array([0, 1, 4, 9])

dot (или, в более общем случае, матричное умножение) выполняется с помощью функции

x.dot(x)
#Out: 14

В Python 3.5 оператор @ был добавлен как оператор инфикса для матричного умножения

x = np.diag(np.arange(4))
print(x)
'''
   Out: array([[0, 0, 0, 0],
   [0, 1, 0, 0],
   [0, 0, 2, 0],
   [0, 0, 0, 3]])
'''
print(x@x)
print(x)
'''
   Out: array([[0, 0, 0, 0],
   [0, 1, 0, 0],
   [0, 0, 4, 0],
   [0, 0, 0, 9]])
'''

Добавить . Возвращает копию с добавленными значениями. НЕ на месте.

#np.append(array, values_to_append, axis=None)
x = np.array([0,1,2,3,4])
np.append(x, [5,6,7,8,9])
# Out: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
x
# Out: array([0, 1, 2, 3, 4])
y = np.append(x, [5,6,7,8,9])
y
# Out: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

hstack . Горизонтальный стек. (столбец столбцов)
vstack . Вертикальный стек. (строка строк)

# np.hstack(tup), np.vstack(tup)
x = np.array([0,0,0])
y = np.array([1,1,1])
z = np.array([2,2,2])
np.hstack(x,y,z)
# Out: array([0, 0, 0, 1, 1, 1, 2, 2, 2])
np.vstack(x,y,z)
# Out: array([[0, 0, 0],
#             [1, 1, 1],
#             [2, 2, 2]])

Доступ к массиву

Синтаксис Slice - это i:j:k где i - начальный индекс (включительно), j - индекс остановки (исключение), а k - размер шага. Как и другие структуры данных python, первый элемент имеет индекс 0:

x = np.arange(10)
x[0]
# Out: 0

x[0:4]
# Out: array([0, 1, 2, 3])

x[0:4:2]
# Out:array([0, 2])

Отрицательные значения рассчитываются с конца массива. -1 поэтому обращается к последнему элементу массива:

x[-1]
# Out: 9
x[-1:0:-1]
# Out: array([9, 8, 7, 6, 5, 4, 3, 2, 1])

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

x = np.arange(16).reshape((4,4))
x
# Out: 
#     array([[ 0,  1,  2,  3],
#            [ 4,  5,  6,  7],
#            [ 8,  9, 10, 11],
#            [12, 13, 14, 15]])

x[1,1]
# Out: 5

x[0:3,0]
# Out: array([0, 4, 8])

x[0:3, 0:3]
# Out: 
#     array([[ 0,  1,  2],
#            [ 4,  5,  6],
#            [ 8,  9, 10]])

x[0:3:2, 0:3:2]
# Out: 
#     array([[ 0,  2],
#            [ 8, 10]])

Транспонирование массива

arr = np.arange(10).reshape(2, 5)

Использование метода .transpose :

arr.transpose()
# Out:  
#      array([[0, 5],
#            [1, 6],
#            [2, 7],
#            [3, 8],
#            [4, 9]])

.T :

arr.T
# Out: 
#     array([[0, 5],
#            [1, 6],
#            [2, 7],
#            [3, 8],
#            [4, 9]])

Или np.transpose :

np.transpose(arr)
# Out:
#     array([[0, 5],
#            [1, 6],
#            [2, 7],
#            [3, 8],
#            [4, 9]])

В случае двумерного массива это эквивалентно стандартной матричной транспозиции (как показано выше). В n-мерном случае вы можете указать перестановку осей массива. По умолчанию это отменяет array.shape :

a = np.arange(12).reshape((3,2,2))
a.transpose() # equivalent to a.transpose(2,1,0)
# Out:
#   array([[[ 0,  4,  8],
#           [ 2,  6, 10]],
#
#          [[ 1,  5,  9],
#           [ 3,  7, 11]]])

Но возможна любая перестановка индексов осей:

a.transpose(2,0,1)
# Out:
#    array([[[ 0,  2],
#            [ 4,  6],
#            [ 8, 10]],
#    
#           [[ 1,  3],
#            [ 5,  7],
#            [ 9, 11]]])

a = np.arange(24).reshape((2,3,4))  # shape (2,3,4)
a.transpose(2,0,1).shape
# Out:
#    (4, 2, 3)

Булевское индексирование

arr = np.arange(7)
print(arr)
# Out: array([0, 1, 2, 3, 4, 5, 6])

Сравнение со скаляром возвращает логический массив:

arr > 4
# Out: array([False, False, False, False, False,  True,  True], dtype=bool)

Этот массив можно использовать для индексирования, чтобы выбрать только числа больше 4:

arr[arr>4]
# Out: array([5, 6])

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

# Two related arrays of same length, i.e. parallel arrays
idxs = np.arange(10)
sqrs = idxs**2

# Retrieve elements from one array using a condition on the other
my_sqrs = sqrs[idxs % 2 == 0]
print(my_sqrs)
# Out: array([0, 4, 16, 36, 64])

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

Метод numpy.reshape (такой же, как numpy.ndarray.reshape ) возвращает массив того же общего размера, но в новой форме:

print(np.arange(10).reshape((2, 5)))   
# [[0 1 2 3 4]
#  [5 6 7 8 9]]

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

a = np.arange(12)
a.reshape((3, 4))
print(a)
# [ 0  1  2  3  4  5  6  7  8  9 10 11]

Тем не менее, можно перезаписать shape атрибут ndarray :

a = np.arange(12)
a.shape = (3, 4)
print(a)
# [[ 0  1  2  3]
#  [ 4  5  6  7]
#  [ 8  9 10 11]]

Сначала это поведение может быть неожиданным, но ndarray s хранятся в смежных блоках памяти, и их shape определяет только то, как этот поток данных следует интерпретировать как многомерный объект.

До одной оси в корте shape может иметь значение -1 . Затем numpy выведет длину этой оси для вас:

a = np.arange(12)
print(a.reshape((3, -1)))
# [[ 0  1  2  3]
#  [ 4  5  6  7]
#  [ 8  9 10 11]]

Или же:

a = np.arange(12)
print(a.reshape((3, 2, -1)))

# [[[ 0  1]
#   [ 2  3]]

#  [[ 4  5]
#   [ 6  7]]

#  [[ 8  9]
#   [10 11]]]

Множественные неопределенные измерения, например a.reshape((3, -1, -1)) , не допускаются и будут ValueError .

Операции вещательного массива

Арифметические операции выполняются по элементам на массивах Numpy. Для массивов одинаковой формы это означает, что операция выполняется между элементами с соответствующими индексами.

# Create two arrays of the same size
a = np.arange(6).reshape(2, 3)
b = np.ones(6).reshape(2, 3)

a
# array([0, 1, 2],
#       [3, 4, 5])
b
# array([1, 1, 1],
#       [1, 1, 1])

# a + b: a and b are added elementwise
a + b
# array([1, 2, 3],
#       [4, 5, 6])

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

# Create arrays of shapes (1, 5) and (13, 1) respectively
a = np.arange(5).reshape(1, 5)
a
# array([[0, 1, 2, 3, 4]])
b = np.arange(4).reshape(4, 1)
b
# array([0],
#       [1],
#       [2],
#       [3])

# When multiplying a * b, slices with the same dimensions are multiplied
# elementwise. In the case of a * b, the one and only row of a is multiplied
# with each scalar down the one and only column of b.
a*b
# array([[ 0,  0,  0,  0,  0],
#        [ 0,  1,  2,  3,  4],
#        [ 0,  2,  4,  6,  8],
#        [ 0,  3,  6,  9, 12]])

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

# Create arrays of shapes (2, 2, 3) and (2, 3) respectively
a = np.arange(12).reshape(2, 2, 3)
a
# array([[[ 0  1  2]
#         [ 3  4  5]]
#
#        [[ 6  7  8]
#         [ 9 10 11]]])
b = np.arange(6).reshape(2, 3)
# array([[0, 1, 2],
#        [3, 4, 5]])

# Executing a*b broadcasts b to each (2, 3) slice of a,
# multiplying elementwise.
a*b
# array([[[ 0,  1,  4],
#         [ 9, 16, 25]],
#
#        [[ 0,  7, 16],
#         [27, 40, 55]]])

# Executing b*a gives the same result, i.e. the smaller
# array is broadcast over the other.

Когда применяется широковещательная передача массива?

Вещание происходит, когда два массива имеют совместимые формы.

Формы сравниваются по компонентам, начиная с конечных. Два измерения совместимы, если они одинаковы или один из них равен 1 . Если одна форма имеет более высокий размер, чем другой, то превосходящие компоненты не сравниваются.

Некоторые примеры совместимых форм:

(7, 5, 3)    # compatible because dimensions are the same
(7, 5, 3)


(7, 5, 3)    # compatible because second dimension is 1  
(7, 1, 3)

(7, 5, 3, 5) # compatible because exceeding dimensions are not compared
      (3, 5)

(3, 4, 5)    # incompatible 
   (5, 5) 

(3, 4, 5)    # compatible 
   (1, 5) 

Вот официальная документация по широковещанию массивов .

Заполнение массива содержимым файла CSV

filePath = "file.csv"
data = np.genfromtxt(filePath)

Многие варианты поддерживаются, см. Официальную документацию для полного списка:

data = np.genfromtxt(filePath, dtype='float', delimiter=';', skip_header=1, usecols=(0,1,3) )

Нумерометр n-мерного массива: ndarray

Основной структурой данных в numpy является ndarray (сокращение от n- мерного массива). ndarray s

  • однородные (т.е. они содержат элементы одного и того же типа данных)
  • содержат элементы фиксированных размеров (заданные формой , кортеж из n положительных целых чисел, которые определяют размеры каждого измерения)

Одномерный массив:

x = np.arange(15)
# array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])
x.shape
# (15,)

Двумерный массив:

x = np.asarray([[0, 1, 2, 3, 4], [5, 6, 7, 8, 9], [10, 11, 12, 13, 14]])
x
# array([[ 0, 1, 2, 3, 4],
# [ 5, 6, 7, 8, 9],
# [10, 11, 12, 13, 14]])
x.shape
# (3, 5)

Трехмерная:

np.arange(12).reshape([2,3,2])

Для инициализации массива без указания его содержимого используйте:

x = np.empty([2, 2])
# array([[ 0., 0.],
# [ 0., 0.]])

Догадка типа данных и автоматическое литье

Тип данных установлен как плавающий по умолчанию

x = np.empty([2, 2])
# array([[ 0., 0.],
# [ 0., 0.]])

x.dtype
# dtype('float64')

Если предоставлены некоторые данные, numpy угадает тип данных:

x = np.asarray([[1, 2], [3, 4]])
x.dtype
# dtype('int32')

Обратите внимание: при выполнении присвоений numpy попытается автоматически ndarray значения в соответствии с ndarray данных ndarray

x[1, 1] = 1.5 # assign a float value
x[1, 1]
# 1 
# value has been casted to int
x[1, 1] = 'z' # value cannot be casted, resulting in a ValueError

Передача массивов

См. Также операции массива вещания .

x = np.asarray([[1, 2], [3, 4]])
# array([[1, 2],
         [3, 4]])
y = np.asarray([[5, 6]])
# array([[5, 6]])

В матричной терминологии мы будем иметь матрицу 2x2 и вектор строки 1x2. Тем не менее мы можем сделать сумму

# x + y
array([[ 6, 8],
       [ 8, 10]])

Это связано с тем, что массив y « растянут » до:

array([[5, 6],
       [5, 6]])

в соответствии с формой x .

Ресурсы:



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow