1. ホーム
  2. 機械学習

numpy詳細チュートリアル

2022-02-24 06:18:11
<パス

基本的なこと

NumPyのメインオブジェクトは、同じ型の要素を持つ多次元配列である。これは、正の整数のタプルでインデックスされた、すべて1つの型の要素(通常は数字である要素)の表です。NumPy では、次元は軸と呼ばれ、軸の数はランクと呼ばれる。

例えば、3次元空間の点の座標[1, 2, 3]は、軸が1つしかないので、ランク1の配列となります。例えば、次の例では、配列のランクは2です(2次元を持つ)。
[[ 1., 0., 0.],
[ 0., 1., 2.]]

NumPyの配列クラスはndarrayと呼ばれる。しばしば配列と呼ばれる。numpy.arrayは、1次元の配列しか扱えず、わずかな機能しか提供しないPythonの標準ライブラリクラスarray.arrayとは違うことに注意してください。より重要なndarrayオブジェクトのプロパティは以下の通りです。

ndarray.ndim
配列の軸の数。Pythonの世界では、軸の数はランクと呼ばれます(行列のランクのように)。

ndarray.shape

配列の次元を表します。これは整数のタプルで、各次元における配列の大きさを表します。たとえば、n 行 m 列の行列は (2,3) の shape 属性を持ち、このタプルの長さは明らかに rank、または dimension、あるいは ndim 属性となります。

ndarray.size
配列の総要素数で、shape プロパティのタプル要素の積に等しい。

ndarray.dtype
配列の要素の型を記述するオブジェクトで、Pythonの標準的な型を使用して作成またはdtypeを指定します。さらに、NumPy は独自のデータ型を提供します。

ndarray.itemsize
配列の各要素のサイズをバイト数で指定します。例えば、float64型の要素の配列はitemizプロパティが8(=64/8)、complex32型の要素の配列はitemプロパティが4(=32/8)である。

ndarray.data
実際の配列要素を含むバッファです。通常、配列の要素は常にインデックスで使用するため、このプロパティを使用する必要はありません。

An example 1
>>> from numpy import *
>>> a = 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
'int32'
>>> a.itemsize
4
>>> a.size
15
>>> type(a)
numpy.ndarray
>>> b = array([6, 7, 8])
>>> b
array([6, 7, 8])
>>> type(b)
numpy.ndarray

配列の作成
配列を作成する方法はいくつかあります。
例えば、通常のPythonのリストやタプルから配列を作成するには、array関数を使用します。作成される配列の型は、元の配列の要素の型から導かれます。

>>> from numpy import *
>>> a = array( [2,3,4] )
>>> a
array([2, 3, 4])
>>> a.dtype
dtype('int32')
>>> b = array([1.2, 3.5, 5.1])
>>> b.dtype
dtype('float64') A common mistake includes calling `array` with multiple numeric arguments instead of providing a list of values as one argument.

>>> a = array(1,2,3,4) # WRONG

>>> a = array([1,2,3,4]) # RIGHT
Arrays transform sequences containing sequences into two-dimensional arrays, sequences containing sequences containing sequences into three-dimensional arrays, etc.

>>> b = array( [ (1.5,2,3), (4,5,6) ] )
>>> b
array([ 1.5, 2. , 3. ],
       [ 4., 5., 6.]])
The array type can be displayed at creation time by specifying

>>> c = array( [ [1,2], [3,4] ], dtype=complex )
>>> c
array([ 1.+0.j, 2.+0.j],
       [ 3.+0.j, 4.+0.j]])

通常、配列は未知の要素数から始まりますが、その大きさは既知です。そのため、NumPyではプレースホルダーを使って配列を作成する関数を多数用意しています。これにより、配列を展開する必要性と演算の高コストを最小限に抑えることができます。

zeros関数はすべての0からなる配列、ones関数はすべての1からなる配列、eye関数はすべての1の対角線のみの配列、empty関数はランダムな内容の配列とメモリ状態に依存する配列を作成する。作成されるデフォルトの配列の型(dtype)は、すべてfloat64です。

>>> zeros( (3,4) )
array([[0., 0., 0., 0., 0.],
       [0., 0., 0., 0.],
       [0., 0., 0., 0., 0.]])
>>> ones( (2,3,4), dtype=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, 1, 1]]], dtype=int16)
>>> empty( (2,3) )
array([[ 3.73603959e-262, 6.02658058e-154, 6.55490914e-260],
       [ 5.30498948e-313, 3.14673309e-307, 1.00000000e+000]])

シリーズを作成するために、NumPy はリストの代わりに配列を返す配列のような関数を提供している。

>>> arange( 10, 30, 5 )
array([10, 15, 20, 25])
>>> arange( 0, 2, 0.3 ) # it accepts float arguments
array([ 0. , 0.3, 0.6, 0.9, 1.2, 1.5, 1.8])

配列が浮動小数点数の引数を使用する場合、浮動小数点数の精度に限界があるため、取得する要素数を予測できないことがよくあります。したがって、ステップサイズを指定するためにrangeを使う代わりに、linspace関数を使って欲しい要素数を受け取るのがよいでしょう。

その他の関数 array, zeros, zeros_like, ones, ones_like, empty, empty_like, arange, linspace, rand, randn, fromfunction, fromfile
配列の印刷

配列を表示するとき、NumPyはネストされたリストのような形式で表示しますが、そのレイアウトは以下のとおりです。

最後の軸は左から右へ印刷されます
後続の軸は上から下へ印刷されます
残りの軸は上から下に向かって印刷され、各スライスは空白行で次のスライスと区切られる
1次元の配列は行として、2次元の数値は行列として、3次元の数値は行列リストとして出力されます。

>>> a = arange(6) # 1d array
>>> print a
[0 1 2 3 4 5]
>>>
>>> b = arange(12).reshape(4,3) # 2d array
>>> print b
[[ 0 1 2]
 [ 3 4 5]
 [ 6 7 8]
 [ 9 10 11]]
>>>
>>> c = 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]]]

If an array is too large for printing, NumPy automatically omits the middle part and prints only the corners

>>> print arange(10000)
[ 0 1 2 ... , 9997 9998 9999]
>>>
>>> print 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]]
To disable this behavior of NumPy and force printing of the entire array, you can set the printoptions parameter to change the printing options.

>>> set_printoptions(threshold='nan')


基本操作

配列の算術演算は要素ごとに行われます。新しい配列が作成され、その結果が格納されます。

>>> a = array( [20,30,40,50] )
>>> b = 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*sin(a)
array([ 9.12945251, -9.88031624, 7.4511316 , -2.62374854])
>>> a<35
array([True, True, False, False], dtype=bool)

NumPyの乗算演算子*が要素ごとの計算を指示する多くの行列言語とは異なり、行列の乗算はdot関数や行列オブジェクトを作成することで実装できます(チュートリアルの行列の章を参照)。

>>> A = array( [[1,1],
...             [0,1]] )
>>> B = array( [[2,0],
...             [3,4]] )
>>> A*B # elementwise product
array([[2, 0],
       [0, 4]])
>>> dot(A,B) # matrix product
array([[5, 4],
       [3, 4]])

演算子の中には、+=や*=のように、新しい配列を作らずに、既存の配列を変更するために使われるものもあります。

>>> a = ones((2,3), dtype=int)
>>> b = random.random((2,3))
>>> a *= 3
>>> a
array([[3, 3, 3],
       [3, 3, 3]])
>>> b += a
>>> b
array([[ 3.69092703, 3.8324276 , 3.0114541 ],
       [ 3.18679111, 3.3039349 , 3.37600289]])
>>> a += b # b is converted to integer type
>>> a
array([[6, 6, 6],
       [6, 6, 6]])

異なる型の配列に対して操作を行う場合、結果の配列はより一般的かつ正確に知ることができます(この動作をアップキャストと呼びます)。

>>> a = ones(3, dtype=int32)
>>> b = linspace(0,pi,3)
>>> b.dtype.name
'float64'
>>> c = a+b
>>> c
array([ 1. , 2.57079633, 4.14159265])
>>> c.dtype.name
'float64'
>>> d = exp(c*1j)
>>> d
array([ 0.54030231+0.84147098j, -0.84147098+0.54030231j,
       -0.54030231-0.84147098j])
>>> d.dtype.name
'complex128' Many non-array operations, such as calculating the sum of all elements of an array, are implemented as methods of the ndarray class

>>> a = random.random((2,3))
>>> a
array([ 0.6903007 , 0.39168346, 0.16524769],
       [ 0.48819875, 0.77188505, 0.94792155]])
>>> a.sum()
3.4552372100521485
>>> a.min()
0.16524768654743593
>>> a.max()
0.9479215542670073
These operations are applied by default to an array as if it were a list of numbers, independent of the shape of the array. However, specifying the axis parameter allows you to apply the operations to the axes specified by the array.

>>> b = 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]])

インデックス、スライス、イテレート

一次元配列は、リストや他のPythonシーケンスと同様に、インデックス付け、スライス、反復処理を行うことができます。

>>> a = 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
Multidimensional arrays can have one index per axis. These indexes are given by a comma-separated tuple.

>>> def f(x,y):
...         return 10*x+y
...
>>> b = 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]])
When less than the number of axes is provided, the missing index is considered to be the entire slice.

>>> b[-1] # the last row. Equivalent to b[-1,:]
array([40, 41, 42, 43])
The expressions in parentheses in b[i] are treated as i and a series of :'s to represent the remaining axes. .


ドット(...)は、完全なインデックス付きタプルを生成するために必要な多くのセミコロンを表します。xがランク5の配列(すなわち5つの軸を持つ)である場合、:

x[1,2,...] は x[1,2,:,:,:] と等価である。
x[...,3] は x[:,:,:,:,:, 3] と等価である。
x[4,...,5,:] は x[4,:,,5,:] と等価である。

>>> c = 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]]) 
Iterated multidimensional arrays are with respect to the first axis :2

>>> 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]
However, if one wants to perform operations on each element of the array, one can use the flat attribute, which is an iterator over the array elements:

>>> 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
For more [], ..., newaxis, ndenumerate, indices, index exp see the NumPy examples

Shape operations
Changing the shape of an array
The shape of an array is given by the number of elements on each of its axes.

>>> a = floor(10*random.random((3,4)))
>>> a
array([ 7., 5., 9., 3.],
       [ 7., 2., 7., 8.],
       [ 6., 8., 3., 2.]])
>>> a.shape
(3, 4)
The shape of an array can be modified by multiple commands.

>>> a.ravel() # flatten the array
array([ 7., 5., 9., 3., 7., 2., 7., 8., 6., 8., 3., 2.])
>>> a.shape = (6, 2)
>>> a.transpose()
array([ 7., 9., 7., 7., 7., 6., 3.],
       [ 5., 3., 2., 8., 8., 2.]])
The order of the elements of the array flattened by ravel() is usually "C-style", that is, the rightmost index changes the fastest, so the element a[0,0] is followed by a[0,1]. NumPy usually creates an array that holds data in this order, so ravel() will always not need to copy its argument.3 However, if the array is sliced into other arrays or has unusual option, it may need to be copied. The reshape() and ravel() functions can also be constructed as FORTRAN-style arrays with a few optional arguments, i.e., the leftmost index changes the fastest.

The reshape function changes the shape of the argument and returns it, while the resize function changes the array itself.

>>> a
array([ 7., 5.],
       [ 9., 3.],
       [ 7., 2.],
       [ 7., 8.],
       [ 6., 8.],
       [ 3., 2.]])
>>> a.resize((2,6))
>>> a
array([ 7., 5., 9., 3., 7., 2.],
       [ 7., 8., 6., 8., 3., 2.]])
If a dimension is given as -1 in the reshape operation, its dimension will be calculated automatically

For more shape, reshape, resize, ravel see the NumPy example

Stacking different arrays
There are several ways to stack arrays along different axes.

>>> a = floor(10*random.random((2,2)))
>>> a
array([ 1., 1.],
       [ 5., 8.]])
>>> b = floor(10*random.random((2,2)))
>>> b
array([ 3., 3.],
       [ 6., 0.]])
>>> vstack((a,b))
array([[ 1., 1.],
       [ 5., 8.],
       [ 3., 3.],
       [ 6., 0.]])
>>> hstack((a,b))
array([[ 1., 1., 3., 3,]
       [ 5., 8., 6., 0.]])
The column_stack function synthesizes a one-dimensional array into a two-dimensional array in columns, which is equivalent to vstack for one-dimensional arrays.

>>> column_stack((a,b)) # With 2D arrays
array([ 1., 1., 3., 3.],
       [ 5., 8., 6., 0.]])
>>> a=array([4.,2.])
>>> b=array([2.,8.])
>>> a[:,newaxis] # This allows to have a 2D columns vector
array([[4.],
       [ 2.]])
>>> column_stack((a[:,newaxis],b[:,newaxis]))
array([ 4., 2.],
       [ 2., 8.]])
>>> vstack((a[:,newaxis],b[:,newaxis])) # The behavior of vstack is different
array([[ 4.],
       [ 2.],
       [ 2.],
       [ 8.]])
The row_stack function, on the other hand, combines one-dimensional arrays in rows into two-dimensional arrays.

For arrays with higher dimensions than two, hstack is combined along the second axis, vstack along the first axis, and concatenate allows optional arguments to give the axis along which to combine.

Note

In complex cases, r_[] and c_[] are useful for creating numbers that are combined along one direction, and they allow range notation (":"):

>>> r_[1:4,0,4]
array([1, 2, 3, 0, 4])
When using arrays as arguments, r_ and c_ behave much like vstack and hstack by default, but allow optional arguments that give the designation of the axis along which the combination is to be used.

For more functions hstack , vstack, column_stack , row_stack , concatenate , c_ , r_ see the NumPy example.

Splitting an array into several smaller arrays
With hsplit you can split an array along its horizontal axis, or specify the number of arrays that return the same shape, or specify the columns after which the splitting occurs:

>>> a = floor(10*random.random((2,12)))
>>> a
array([ 8., 8., 3., 9., 0., 4., 3., 0., 0., 0., 6., 4., 4,
       [ 0., 3., 2., 9., 6., 0., 4., 5., 7., 5., 1., 4.]])
>>> hsplit(a,3) # Split a into 3
[array([[ 8., 8., 3., 9.]],
       [ 0., 3., 2., 9.]]), array([[ 0., 4., 3., 0.],
       [ 6., 0., 4., 5.]]), array([[ 0., 6., 4., 4,]
       [ 7., 5., 1., 4.]])]
>>> hsplit(a,(3,4)) # Split a after the third and the fourth column
[array([[ 8., 8., 3.],
       [ 0., 3., 2.]]), array([[ 9.],
       [ 9.]]), array([[ 0., 4., 3., 0., 0., 6., 4., 4,]
       [ 6., 0., 4., 5., 7., 5., 1., 4.]])]
vsplit splits along the vertical axis, array split allows to specify along which axis to split.



レプリケーションとビュー
配列を計算したり操作したりするとき、そのデータは新しい配列にコピーされる場合とされない場合があります。これは、初心者をしばしば混乱させる原因となっています。このようなケースは3つあります。

全くコピーしない
単純代入では、配列オブジェクトやそのデータはコピーされません。

>>> a = 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)

Pythonは不定形オブジェクトを参照4として渡すので、関数呼び出しでは配列がコピーされない。

>>> def f(x):
...     print id(x)
...
>>> id(a) # id is a unique identifier of an object
148293216
>>> f(a)
148293216

表示と浅いコピー
異なる配列オブジェクトが同じデータを共有する。ビューメソッドは、同じデータを指す新しい配列オブジェクトを作成します。

>>> 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]])
The sliced array returns one of its views.

>>> 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]])
Deep Copy
This copy method copies the array and its data exactly.

>>> 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]])
Overview of functions and methods
This is a categorized list of NumPy functions and methods. The names are linked to NumPy examples, and you can see these functions in action. [^5]


アドバンスド

ブロードキャストルール(ルール)
ブロードキャストルールは、ジェネリック関数が同じ形でない入力を有意義に処理することを可能にする。

ブロードキャストの最初の規則は、すべての入力配列が同じ次元でない場合、すべての配列が同じ次元になるまで、小さい次元の配列に繰り返し "1"を追加することである。

放送の第二法則では、長さ1の配列は特定の方向に対して、その方向に沿った最大の形状の大きさを持つかのように振舞うと決められています。配列の場合、その次元に沿った配列要素の値は同じであることが前提となっています。

ブロードキャストルールを適用した後、すべての配列のサイズが一致する必要があります。詳細はこのドキュメントに記載されています。

派手なインデックス作成とインデックス作成のトリック
NumPyには、通常のPythonの配列よりも多くのインデックス機能があります。前に見たように、整数とスライスのインデックスに加えて、配列は整数配列とブーリアン配列の両方のインデックスを持つことができます。

Indexing by arrays
>>> a = arange(12)**2 # the first 12 square numbers
>>> i = 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 = array( [ [ 3, 4], [ 9, 7 ] ] ) # a bidimensional array of indices
>>> a[j] # the same shape as j
array([[ 9, 16],
       [81, 49]])
When the indexed array a is multidimensional, each unique indexed column points to the first dimension of a.5 The following example demonstrates this behavior by converting the image labels to color images using a toned-down version.

>>> palette = array( [ [0,0,0], # black
...                    [255,0,0], # red
...                    [0,255,0], # green
...                    [0,0,255], # blue
...                    [255,255,255] ]) # white
>>> image = 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],
        [[0, 0, 0], [[255, 0, 0]],
        [ 0, 255, 0],
        [ 0, 0, 0]],
       [[ 0, 0, 0],
        [ 0, 0,

>>> a = array([2,3,4,5])
>>> b = array([8,5,4])
>>> c = array([5,4,6,8,3])
>>> ax,bx,cx = 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
You can also implement the following simplification.

def ufunc_reduce(ufct, *vectors):
    vs = ix_(*vectors)
    r = ufct.identity
    for v in vs:
        r = ufct(r,v)
    return r
Then use it like this.

>>> ufunc_reduce(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]]])
The advantage of this reduce over ufunc.reduce (say add.reduce) is that it makes use of the broadcast rule, avoiding the need to create an array of parameters whose output size is multiplied by the number of vectors.8

Indexing with strings
See RecordArray.

Linear Algebra
Moving on, basic linear algebra is included here.

Simple array operations
Refer to linalg.py in the numpy folder for more information

>>> from numpy import *
>>> from numpy.linalg import *

>>> a = array([[1.0, 2.0], [3.0, 4.0]])
>>> print a
[[ 1. 2.]
 [ 3. 4.]]

>>> a.transpose()
array([ 1., 3.],
       [ 2., 4.]])

>>> inv(a)
array([[-2., 1.],
       [ 1.5, -0.5]])

>>> u = eye(2) # unit 2x2 matrix; "eye" represents "I"
>>> u
array([ 1., 0.],
       [ 0., 1.]])
>>> j = array([[0.0, -1.0], [1.0, 0.0]])

>>> dot (j, j) # matrix product
array([[-1., 0.],
       [ 0., -1.]])

>>> trace(u) # trace
 2.0

>>> y = array([[5.], [7.]])
>>> solve(a, y)
array([[-3.],
       [ 4.]])

>>> 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]`` .
Matrix classes
This is a short introduction to the matrix class.

>>> A = matrix('1.0 2.0; 3.0 4.0')
>>> A
[[ 1. 2.]
 [ 3. 4.]]
>>> type(A) # file where class is defined
<class 'numpy.matrixlib.defmatrix.matrix'>

>>> A.T # transpose
[[ 1. 3.]
 [ 2. 4.]]

>>> X = matrix('5.0 7.0')
>>> Y = X.T
>>> Y
[[5.]
 [7.]]

>>> print A*Y # matrix multiplication
[[19.]
 [43.]]

>>> print A.I # inverse
[[-2. 1.]]
 [ 1.5 -0.5]]

>>> solve(A, Y) # solving linear equation
matrix([[-3.],
        [ 4.]])
Index: Comparing matrices and two-dimensional arrays
Note that there are some important differences between arrays and matrices in NumPy. numPy provides two basic objects: an N-dimensional array object and a generic function object. All other objects are built on top of them. In particular, a matrix is a two-dimensional array object that inherits from the NumPy array object. For both arrays and matrices, the index must contain one or more of these combinations: integer scalars, ellipses, lists of integers; boolean values, tuples of integers or boolean values, and a one-dimensional array of integers or boolean values. Matrices can be used as indices of matrices, but usually arrays, lists, or other forms are needed to accomplish this task.

As usual in Python, the index starts at 0. Traditionally, we represent a two-dimensional array or matrix with rectangular rows and columns, where the rows are called rows along the 0-axis and columns along the 1-axis.9

Let us create arrays and matrices for slicing.

&g