Рубрики
Без рубрики

Numpy массивы в Lightspeed ⚡ Часть 3

В этом посте я расскажу о некоторых частях Numpy, которые хорошо подходят, когда вы используете его. Этот… Tagged с Python.

Python-Numpy (5 серии деталей)

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

Немного больше индексации

Вы также можете изменить массив, установив его форма Собственность в кортеж для нового размера, как x.shape = (2,5) .

Скажем, у вас есть этот большой массив: Z.Arange (81) .Reshape (3,3,3,3) Анкет Индексирование массива с использованием списков индексов отличается от использования кортежей индексов.

>>> z[[1,1,1,1]] # Grabs the entire second dimension, and makes four copies of it on another array
array([[[[27, 28, 29],
         [30, 31, 32], ...
>>> z[(1,1,1,1)] # Gets the element in the corresponding array coordinate/position
40

Ellipsis можно использовать в качестве сокращения для целых ломтиков промежуточных измерений. Среции тоже также работают:

>>> z[1, Ellipsis, 1]       # same as [1,...,1], itself same as [1, :, :, 1]
array([[28, 31, 34],
       [37, 40, 43],
       [46, 49, 52]])
>>> z[1,1,1,slice(0,2)]     # same as [1,1,1,0:2]
array([39, 40])

Кажется, что вмешательство не влияет на индексацию, поэтому использование z [(1,1)] это то же самое, что и с использованием z [1,1] Анкет Вы даже можете создать переменную индексации без кортежа, любезно предоставленного синтаксисом Python.

>>> indices = 1, Ellipsis, 1    # Same as (1, Ellipsis, 1)
>>> z[indices]
array([[28, 31, 34],
       [37, 40, 43],
       [46, 49, 52]])

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

>>> x = np.arange(0, 50, 10)
>>> x
array([ 0, 10, 20, 30, 40])
>>> x[np.array([1, 1, 3, 1])] += 1    # Doesn't work properly
>>> x
array([ 0, 11, 20, 31, 40])

Вместо этого сделайте что -то подобное:

>>> x[np.array([3])] += 1
>>> x[np.array([1])] += 3
>>> x
array([ 0, 13, 20, 31, 40])         # You probably meant to to do this

Типы данных

Numpy имеет несколько типов данных, которые соответствуют типам C. Они могут быть использованы там, где dtype Аргумент ключевого слова разрешен.

Существуют определяемые платформы типы, которые соответствуют типам, для которых вы использовали на процедурных языках, таких как C и C ++, а также типы, которые всегда содержат определенное количество битов. Ниже приведены Скалярные типы которые не являются экземплярами объектов dtype, но могут использоваться вместо объекта dtype, то есть любой функции, где dtype Аргумент ключевого слова принимается.

буль Логический (истинный или ложный) хранится как байт np.bool_
Подписанный Чар Определяется платформой np.byte
без подписи Чар Определяется платформой np.ubyte
короткая Определяется платформой np.short
без подписи короткой Определяется платформой np.ushort
инт Определяется платформой np.intc
Unsigned int Определяется платформой np.uintc
длинная Определяется платформой np.int_
без знака длинная Определяется платформой np.uint
долго долго Определяется платформой np.longlong
без подписи долго Определяется платформой np.ulonglong
Половина точности поплавка: бит знака, 5 бит показания, 10 битов Мантисса np.half / np.float16
плавать Определенная платформой единственная точная поплавка: обычно подписывает бит, 8 битов, 23 бита Mantissa np.single
двойной Платформа, определенная двойная точность: обычно бит подписывания, 11 битов, 52 бита Mantissa. np.float / np.double
длинный двойной Платформа, определенный с расширенной режиссером np.longdouble
float _complex Комплексное число, представленное двумя сплавами с одной режиссером (реальные и мнимые компоненты) np.csingle
Двойной _complex Комплексное число, представленное двумя поплавками с двойной задачей (реальные и воображаемые компоненты). np.cfloat / np.cdouble
Длинный двойной _complex Комплексное число, представленное двумя поплавками с расширенной зависимостью (реальные и воображаемые компоненты). np.clongdouble
int8_t Байт (от -128 до 127) np.int8
int16_t Целое число (от -32768 до 32767) np.int16
int32_t Integer (-2147483648 до 2147483647) np.int32
int64_t Integer (-9223372036854775808 до 9223372036854775807) np.int64
uint8_t Unsigned Integer (от 0 до 255) np.uint8
uint16_t Unsigned Integer (от 0 до 65535) np.uint16
uint32_t Unsigned Integer (от 0 до 4294967295) np.uint32
uint64_t Unsigned Integer (от 0 до 18446744073709551615) np.uint64
intptr_t Целое число используется для индексации, как правило, то же самое, что и ssize_t np.intp
uintptr_t Целое число достаточно большого, чтобы удерживать указатель np.uintp
плавать np.float32
двойной Обратите внимание, что это соответствует точности встроенного питона. np.float64 / np.float_
float _complex Комплексное число, представленное двумя 32-битными поплавками (реальные и мнимые компоненты) np.complex64
Двойной _complex Обратите внимание, что это соответствует точности комплекса Python встроенного питона. np.complex128 / np.complex _

Внимательно посмотрите на стол. Некоторые типы Numpy не имеют такого же размера, как и аналогичные аналоги C. Особенно:

  • np.uint не подписывается долго, а не без подписи инт.
  • np.float и np.cfloat такого же размера, что и двойной и двойной _complex C, соответственно.

(Читать подобные таблицы хороши, так как я не знал, что у C и C ++ до сих пор имел тип плавания/двойного комплекса.)

Призыв np. () В качестве функции с любыми числами, списками или NDARRAYS, которые вы хотите разыграть, бросит их в NDARRAY такого типа. Таким образом, эти функции ведут себя как C’s (int) или c ++ ‘s static_cast Анкет Пример:

In [1]: np.uint8([1,2,3])                                                       
Out[1]: array([1, 2, 3], dtype=uint8)
# This also works:
In [2]: np.array([1,2,3]).astype(np.int8)                                       
Out[2]: array([1, 2, 3], dtype=int8)

Есть некоторые «метатипы», в частности, общие типы существует в Numpy, которые описывают классы типов, такие как целые числа и номера с плавающими темпами. Одним из их применений является выяснение типа элемента:

>>> d = np.dtype(int)
>>> d
dtype('int32')

>>> np.issubdtype(d, np.integer)
True

>>> np.issubdtype(d, np.floating)
False

Общие типы: число, неточное, плавающее, комплексное, протекающее, Integer, SignteNteger, UnsignTeger, символ, универсальный, гибкий и недействительный. Я создал скрипт, который будет классифицировать каждый DTYPE в соответствии с их подтипом. Если печатать, является ли каждый Numpy Dtype, является подтипом общего типа. Я думал об аннотировании таблицы выше с этими результатами Но тогда это будет слишком загромождено.

In [1]: np_types = ["bool_", "byte", "ubyte", "short", "ushort", "intc", "uintc
   ...: ", "int_", "uint", "longlong", "ulonglong", "half", "single", "float16"
   ...: , "float", "double", "longdouble", "csingle", "cfloat", "cdouble", "clo
   ...: ngdouble", "int8", "int16", "int32", "int64", "uint8", "uint16", "uint3
   ...: 2", "uint64", "intp", "uintp", "float32", "float64", "float_", "complex
   ...: 64", "complex128", "complex_"]
In [2]: np_generics = [np.number, np.inexact, np.floating, np.complexfloating, 
   ...: np.integer, np.signedinteger, np.unsignedinteger, np.character, np.gene
   ...: ric, np.flexible] 
In [3]: for dt in np_types: 
   ...:     for gn in np_generics: 
   ...:         print("{0} is {1}: {2}".format(dt, gn.__name__, np.issubdtype(dt, gn))) 
bool_ is number: False
bool_ is inexact: False
bool_ is floating: False
bool_ is complexfloating: False
bool_ is integer: False
bool_ is signedinteger: False
bool_ is unsignedinteger: False
bool_ is character: False
bool_ is generic: True
bool_ is flexible: False
byte is number: True
byte is inexact: False
byte is floating: False
...

Больше типов данных

Существует больше комбинаций объектов, которые может указать DTYPE, чем просто целые числа и номера с плавающей запятой. Они также могут представлять байтовый порядок, имена поля и типы внутри типа, если это структура, а форма и дата данных элементов, если dtype – это массив, и даже тип void (для необработанных данных).

Это позволяет dtypes эмулировать полную гамму типов C и C ++ без применения строгого типирования, присутствующего на этих языках.

Строка dtype состоит из следующих символов, по порядку:

  • > Для Большого Энда, < Для маленького эндьяна и = Для оборудования по умолчанию
  • персонаж, обозначающий тип. Может быть ? для логического, b для подписанного байта, B для безписанного байта, я Для подписанного целого числа, U Для беспингевого целого числа, f для плавающего запястья, C Для сложной плавающей запятой, m для Timedelta Python объект, M для DateTime объект, O для какого -то другого объекта Python, U для строки Unicode и V Для пустоты или необработанных данных void редко необходим
  • Количество байты в типе. (Для строки Unicode это количество символов вместо этого)
>>> dt = np.dtype('i4')   # 32-bit signed integer
>>> dt = np.dtype('f8')   # 64-bit floating-point number
>>> dt = np.dtype('c16')  # 128-bit complex floating-point number
>>> dt = np.dtype('a25')  # 25-length zero-terminated bytes
>>> dt = np.dtype('U25')  # 25-character string

В начале последовательности символов dtype вы можете вставить размеры, такие как (3,2) , что делает его массивом 3×2 такого типа.

Вы можете поместить несколько dtypes в одну и ту же строку, разделенную запятыми, чтобы представлять структуру. Структы могут быть проиндексированы строками «F0», «F1» и т. Д. Если вы не даете структуру разные имена поля. Вот как будет выглядеть все:

# Array dtype
In [1]: dt = np.dtype(('(2,3)U4'))                                            

In [2]: np.array([(('fffeee', '4', '5'), 'b'), 'as', 'dw'], dt)               
Out[2]: 
array([[['fffe', '4', '5'],
        ['b', 'b', 'b']],

       [['a', 'a', 'a'],
        ['s', 's', 's']],

       [['d', 'd', 'd'],
        ['w', 'w', 'w']]], dtype=' in 
---------> 1 np.array([(('fffeee', '4', '5'), 'b'), 'as', 'dw'], dt)['f0']

IndexError: only integers, slices (`:`), ellipsis (`...`), numpy.newaxis (`None`) and integer or boolean arrays are valid indices


# Structure dtype
In [4]: dt = np.dtype(('i4, U4, f4'))     # fields default to 'f0', 'f1', 'f2'

In [5]: np.array([(1, 'a', 1.23), (2, 'b', 2.4), (3, 'c', 2.3)], dt)           
Out[5]: 
array([(1, 'a', 1.23), (2, 'b', 2.4 ), (3, 'c', 2.3 )],
      dtype=[('f0', '

Теперь, когда мы ушли с дороги, есть другие форматы параметров np.dtype () может взять:

  • dtype (type) где Тип любая строка в np.sctypedict.keys () Анкет Стоит уточнить это np.sctypedict () Содержит сопоставления между всеми типами Numpy Dtypes до скалярных типов с фиксированной шириной.
  • dtype (glebible_dtype, itempize) где Гибкий_дтип это тип Numpy, и itemsize это количество байтов, которые потребуются. Это имеет смысл только для типов ширины переменной, таких как строка Unicode и void. Другие типы не будут почтить itemsize Анкет
In [1]: np.dtype(np.int, 10)                                                  
Out[1]: dtype('int64')

In [2]: np.dtype('U', 10)                                                     
Out[2]: dtype('
  • dtype (gibleble_dtype, shape) , то же самое, что и выше, но форма может быть кортежом из размеров массива.
  • dtype ([((field_name, field_dtype, shape), ...]) делает тип массива. Он имеет название поля, за которым следует его форма, и введите строку, как сформулировано выше. Примечание: Строка dtype также может сделать массивы.
In [1]: dt = np.dtype([('R','u1'), ('G','u1'), ('B','u1'), ('A','u1')])

In [2]: np.array([(1,1,1,1), (2,2,22,2)], dt)                                 
Out[2]: 
array([(1, 1,  1, 1), (2, 2, 22, 2)],
      dtype=[('R', 'u1'), ('G', 'u1'), ('B', 'u1'), ('A', 'u1')])

In [3]: np.array([(1,1,1,1), (2,2,22,2)], dt)['G']                            
Out[3]: array([1, 2], dtype=uint8)
  • dtype ({'names': , 'formats': , 'смещения': , 'titles': , 'itemize': }) , это делает структуру, где имена это список имен поля, форматы это список строк DTYPE или скалярных типов Numpy, смещение Может использоваться только для прокладки целых чисел dtypes (это список смещений в структуре, которое каждое поле, как и структуры C), названия это список текстовых описаний каждого поля и itemsize это размер, к которому должен быть дополнен весь dtype, который вы можете сделать больше, чем фактический размер структуры, если хотите, например, Совместите это с силой 2. Примечание: Строка dtype также может изготовлять структуры.
In [1]: dt = np.dtype({'names': ['r','g','b','a'], 
   ...:                'formats': [np.uint8, np.uint8, np.uint8, np.uint8]})

In [2]: np.array([(1,2,3,4),(5,256,265,255)],dt)                              
Out[2]: 
array([(1, 2, 3,   4), (5, 0, 9, 255)],
      dtype=[('r', 'u1'), ('g', 'u1'), ('b', 'u1'), ('a', 'u1')])

In [3]: np.array([(1,2,3,4),(5,256,265,255)],dt)['r']                         
Out[3]: array([1, 5], dtype=uint8)

  • dtype ((base_dtype, new_dtype))) , создает объект new_dtype Но маскирует это как base_dtype Анкет
In [1]: dt = np.dtype((np.int32,{'real':(np.int16, 0),'imag':(np.int16, 2)}))

In [2]: np.array([(6+(6<<20),5+(5<<20)),(4+(4<<20), 3+(3<<20))],dt)           
Out[2]: 
array([[6291462, 5242885],
       [4194308, 3145731]],
      dtype=(numpy.int32, [('real', '

Это грубый взлом для использования нижних битов Int32 в качестве реального числа и верхних битов в качестве воображаемого номера.

In [1]: dt = np.dtype(('u4', [('r','u1'),('g','u1'),('b','u1'),('a','u1')]))

In [2]: np.array([-1,-2,-3,-4], dt)                                           
Out[2]: 
array([4294967295, 4294967294, 4294967293, 4294967292],
      dtype=(numpy.uint32, [('r', 'u1'), ('g', 'u1'), ('b', 'u1'), ('a', 'u1')]))

In [3]: np.array([-1,-2,-3,-4], dt)['r']                                      
Out[3]: array([255, 254, 253, 252], dtype=uint8)

In [4]: np.array([-1,-2,-3,-4], dt)['g']                                      
Out[4]: array([255, 255, 255, 255], dtype=uint8)

Этот метод формулировки DTYPE также позволил бы вам получить доступ к красным, зеленым, синим и альфа -частям цвета путем индексации, без необходимости делать множество структур или выполнять бить. Вместо этого он завершает все эти типы вокруг uint32 Анкет

Полезные члены Dtype

Следующие участники – это в основном вещи, которые я перешел в вышеупомянутых разделах, но им удобно иметь удобный для программного доступа:

  • .type : Базовый тип, используемый Numpy для этого dtype
  • .cind : Один из приведенных выше кодов символов, который определяет тип
  • .CHAR и .num : Больше идентификаторов типа
  • .str : Строка dtype, более формально известная как массив-протокол тип
  • . : Название dtype
  • . size : Количество байтов, которые занимает этот dtype
  • .byteorder : Персонаж, описывающий эндийский порядок этого DTYPE

Для препаратов у вас также есть доступ:

  • .fields : Словарь имен полей и их dtypes. Это нет, если нет полей.
  • . : Список имен поля. Это нет, если нет полей.

Для массивов у вас также есть доступ:

  • .subdtype : Суть его dtype и формы. Это нет, если не массив dtype.
  • .subdtype : Массив Dtype’s Shape Tuple. Это () Если не массив dtype.

Массив скаляры

Один элемент из массива Numpy также является типом Numpy. Последовательность типов между элементами и массивами дает элементам большинство участников, которые доступны для массивов. Например, у вас есть dtype , размер , RESHAPE () и transpose () среди многих других.

Числовые ограничения

Написав в C, типы данных Numpy не переполнены, как числовые типы Python. Таким образом, вы можете проверить минимальные и максимальные значения каждого типа с np.linfo () Для целочисленных типов и np.finfo () Для типов плавающей запятой.

In [1]: np.iinfo(np.int64)                                                     
Out[1]: iinfo(min=-9223372036854775808, max=9223372036854775807, dtype=int64)

In [2]: np.finfo(np.float64)                                                   
Out[2]: finfo(resolution=1e-15, min=-1.7976931348623157e+308, max=1.7976931348623157e+308, dtype=float64)

Теперь слово о точности с плавающей запятой, поскольку известно, что целочисленная точность ограничена количеством битов, которые у него есть:

Python использует 64-битные поплавки (другими словами двойной ) для представления поплавок. У Numpy есть свои типы поплавок. В частности, он также имеет длинный двойной -Поподобный 80-битный тип плавающей запятой, который вы видели выше ( np.longdouble ), если вы не используете Windows, в этом случае длинный двойной это всего лишь 64-битный поплавок из-за компилятора Windows, MSVC. Теперь np.longdouble является наиболее точным типом плавающей запятой, который возможен в Numpy, но в Симпи Пакет, если вам действительно нужна более точность или неограниченная точность. Это не будет освещено в этом посте.

За пределами Numpy, дополнительная точность, предлагаемая np.longdouble , если таковые имеются, будут потеряны при преобразовании его в 64-разрядный тип плавания Python, например, если вы хотите отформатировать его в строку, или вызовать любую функцию Python (не Numpy), которая ожидает Python плавать .

np.finfo (np.longdouble) .eps это наименьшее представительное длинное двойное число. Если правильные значения с np.longdouble важно для вас, проверьте, что прохождение 1 и 1 + np.finfo (np.longdouble) .eps К вашим функциям не раздается тем же числу, особенно если длинные парни составляют 80 бит в вашей системе, как EPS будет потерян при преобразовании в Python Float, вызывая эквивалентные оба значения (до 1).

А также были сделаны

Много материала было получено из Numpy Manual Анкет

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

Изображение по Arek socha от Pixabay

Python-Numpy (5 серии деталей)

Оригинал: “https://dev.to/zenulabidin/numpy-arrays-at-lightspeed-part-3-47g3”