Часто я задаю ТАК вопрошающие, что такое shape
?dtype
?даже type
.Отслеживание этих свойств является важной частью хорошего numpy
программирования.Даже в MATLAB я обнаружил, что получение size
права было 80% отладки.
type
Пример squeeze
вращается вокруг type
, класс ndarray
против np.matrix
подкласс:
In [160]: np.squeeze(np.array([[1, 1]]))
Out[160]: array([1, 1])
In [161]: np.squeeze(np.matrix([[1, 1]]))
Out[161]: matrix([[1, 1]])
np.matrix
объект по определению всегда 2d.В этом суть переопределения ndarray
операций.
Многие numpy
функции делегируют свою работу methods. The code for
np.squeeze`:
try:
squeeze = a.squeeze
except AttributeError:
return _wrapit(a, 'squeeze')
try:
# First try to use the new axis= parameter
return squeeze(axis=axis)
except TypeError:
# For backwards compatibility
return squeeze()
Так что In [161]
isдействительно:
In [163]: np.matrix([[1, 1]]).squeeze()
Out[163]: matrix([[1, 1]])
np.matrix.squeeze
имеет собственную документацию.
Как правило, мы не рекомендуем использовать np.matrix
.Он был создан много лет назад, чтобы облегчить жизнь непослушным программистам MATLAB.В те дни у MATLAB были только 2d матрицы (даже сейчас MATLAB 'скаляры' являются 2d).
dtype
np.array
- мощная функция.Обычно его поведение интуитивно понятно, но иногда оно делает слишком много предположений.
Обычно он принимает подсказки от ввода, будь то целое число, число с плавающей запятой, строка и / или списки:
In [170]: np.array(1).dtype
Out[170]: dtype('int64')
In [171]: np.array(1.0).dtype
Out[171]: dtype('float64')
Но он предоставляет ряд параметров.Используйте их, если вам нужно больше контроля:
array(object, dtype=None, copy=True, order='K', subok=False, ndmin=0)
In [173]: np.array(1, float).dtype
Out[173]: dtype('float64')
In [174]: np.array('1', float).dtype
Out[174]: dtype('float64')
In [177]: np.array('1', dtype=float,ndmin=2)
Out[177]: array([[1.]])
Посмотрите его документы, а также страницу https://docs.scipy.org/doc/numpy/reference/routines.array-creation.html, на которой перечислены многие другие функции создания массива.Посмотрите также на некоторый их код.
Например, np.atleast_2d
выполняет много проверок shape
:
def atleast_2d(*arys):
res = []
for ary in arys:
ary = asanyarray(ary)
if ary.ndim == 0:
result = ary.reshape(1, 1)
elif ary.ndim == 1:
result = ary[newaxis,:]
else:
result = ary
res.append(result)
if len(res) == 1:
return res[0]
else:
return res
Подобные функции являются хорошими примерами защитного программирования.
Мы получаем много ТАК вопросов о 1d массивах с dtype=object
.
In [272]: np.array([[1,2,3],[2,3]])
Out[272]: array([list([1, 2, 3]), list([2, 3])], dtype=object)
np.array
пытается создать многомерный массив с униформой dtype
.Но если элементы различаются по размеру или не могут быть преобразованы в один и тот же dtype
, он вернется к типу object
dtype.Это одна из тех ситуаций, когда нам нужно обратить внимание на shape
и dtype
.
вещание
Вещание было частью numpy
навсегда, и нет никакого способавыключая егоOctave и MATLAB добавили его позже и включили предупреждающие переключатели.
Первый защитный шаг - понять принципы вещания, а именно:
- , он может расширить начальные измерения, чтобы соответствовать
- это приводит к унитарным измерениям для сопоставления.
Итак, базовый пример:
In [180]: np.arange(3)[:,None] + np.arange(4)
Out[180]:
array([[0, 1, 2, 3],
[1, 2, 3, 4],
[2, 3, 4, 5]])
Первый член (3,) расширен до (3,1).Вторым является (4,), который в результате трансляции расширяется до (1,4).Совместно (3,1) и (1,4) транслируются на (3,4).
У многих простых функций есть параметры, облегчающие отслеживание размеров.Например, sum
(и другие) имеет параметр keepdims
:
In [181]: arr = _
In [182]: arr.sum(axis=0)
Out[182]: array([ 3, 6, 9, 12]) # (4,) shape
In [183]: arr.sum(axis=0,keepdims=True)
Out[183]: array([[ 3, 6, 9, 12]]) # (1,4) shape
In [184]: arr/_ # (3,4) / (1,4) => (3,4)
Out[184]:
array([[0. , 0.16666667, 0.22222222, 0.25 ],
[0.33333333, 0.33333333, 0.33333333, 0.33333333],
[0.66666667, 0.5 , 0.44444444, 0.41666667]])
В этом случае keepdims
не является обязательным, поскольку (3,4) / (4,) работает.Но с суммой axis=1
форма становится (3,), которая не может транслироваться с (3,4).Но (3,1) может:
In [185]: arr/arr.sum(axis=1,keepdims=True)
Out[185]:
array([[0. , 0.16666667, 0.33333333, 0.5 ],
[0.1 , 0.2 , 0.3 , 0.4 ],
[0.14285714, 0.21428571, 0.28571429, 0.35714286]])
Для управления фигурами мне нравится:
- отображение
shape
при отладке - тестирование фрагментов в интерактивном режиме
- тест с диагностическими формами, например
np.arange(24).reshape(2,3,4)
assertion
операторы в функциях могут быть полезны assert(arr.ndim==1)
ввод
Последние Python 3В версии добавлен typing
модуль
https://docs.python.org/3/library/typing.html
Даже для встроенных типов Python он предварительный.Я не уверен, что многое было добавлено для numpy
.