📜 ⬆️ ⬇️

NumPy, a guide for beginners. Part 1

NumPyLogo NumPy is an extension of the Python language that adds support for large multi-dimensional arrays and matrices, along with a large library of high-level math functions for operations with these arrays.

The first part of the textbook talks about the basics of working with NumPy: creating arrays, their attributes, basic operations, element-wise application of functions, indexes, slices, iteration. We consider various manipulations with the transformation of the shape of an array, the union of arrays of several, and vice versa - splitting one into several smaller ones. At the end we will discuss shallow and deep copying.

The basics


If you have not installed NumPy, you can take it here . The version of Python used is 2.6.

The main NumPy object is a homogeneous multidimensional array. This is a table of elements (usually numbers), all of the same type, indexed by sequences of natural numbers.
')
By “multidimensionality” of an array, we mean that it can have several dimensions or axes . Since the word “measurement” is ambiguous, instead of it we will more often use the words “axis” (axis) and “axes” (axes). The number of axes is called a rank .

For example, the coordinates of a point in three-dimensional space [1, 2, 1] are an array of rank 1; it has only one axis. The length of this axis is 3. Another example is an array.

[[ 1., 0., 0.],
[ 0., 1., 2.]]


represents an array of rank 2 (that is, it is a two-dimensional array). The length of the first dimension (axis) is 2, the length of the second axis is 3. For more information, see the Numpy glossary .

The class of multidimensional arrays is called ndarray . Note that this is not the same as the array class of the standard Python standard library, which is used only for one-dimensional arrays. The most important attributes of ndarray objects:

ndarray.ndim is the number of axes (dimensions) of the array. As already mentioned, in the Python world, the number of dimensions is often called rank.

ndarray.shape - the size of the array, its shape. This is a tuple of natural numbers, showing the length of the array along each axis. For a matrix of n rows and m columns, the shape will be (n,m) . The number of elements of a tuple shape is equal to the rank of the array, that is, ndim .

ndarray.size is the number of all elements of the array. Equal to the product of all elements of the shape attribute.

ndarray.dtype is an object describing the type of the elements of an array. You can define dtype using standard Python data types. NumPy here provides a whole bunch of possibilities, for example: bool_, character, int_, int8, int16, int32, int64, float_, float8, float16, float32, float64, complex_, complex64, object_ .

ndarray.itemsize is the size of each array element in bytes. For example, for an array of float64 itemsize value is 8 (= itemsize ), and for complex32 this attribute is 4 (= complex32 ).

ndarray.data is a buffer containing the actual elements of the array. Usually we will not need to use this attribute, because we will access the elements of an array using indexes.

Example


Define the following array:
Copy Source | Copy HTML<br/>>>> from numpy import *<br/>>>> a = arange( 10 ).reshape( 2 , 5 )<br/>>>> a<br/> array ([[ 0 , 1 , 2 , 3 , 4 ],<br/> [ 5 , 6 , 7 , 8 , 9 ]]) <br/>


We have just created an array object named a . Array a has several attributes or properties. In Python, the attributes of a single object are denoted as name_of_object.attribute . In our case:

You can check all these attributes by simply typing them online:
Copy Source | Copy HTML<br/>>>> a.shape<br/>( 2 , 5 )<br/>>>> a.dtype.name<br/> 'int32' <br/>

And so on.

Creating arrays


There are many ways to create an array. For example, you can create an array from regular Python lists or tuples using the array() function:
Copy Source | Copy HTML<br/>>>> from numpy import *<br/>>>> a = array ( [ 2 , 3 , 4 ] )<br/>>>> a<br/> array ([ 2 , 3 , 4 ])<br/>>>> type (a)<br/><type 'numpy.ndarray' > <br/>


The array() function transforms nested sequences into multi-dimensional arrays. The type of the array depends on the type of elements in the source sequence.
Copy Source | Copy HTML<br/>>>> b = array ( [ ( 1 . 5 , 2 , 3 ), ( 4 , 5 , 6 ) ] ) # float <br/>>>> b<br/> array ([[ 1 . 5 , 2 . , 3 . ],<br/> [ 4 . , 5 . , 6 . ]]) <br/>


Once we have an array, we can take a look at its attributes:
Copy Source | Copy HTML<br/>>>> b.ndim # <br/> 2 <br/>>>> b.shape # <br/>( 2 , 3 )<br/>>>> b.dtype # (8- float) <br/>dtype( 'float64' )<br/>>>> b.itemsize # <br/> 8 <br/>


The type of the array can be explicitly specified at the time of creation:
Copy Source | Copy HTML<br/>>>> c = array ( [ [ 1 , 2 ], [ 3 , 4 ] ], dtype=complex )<br/>>>> c<br/> array ([[ 1 .+ 0 .j, 2 .+ 0 .j],<br/> [ 3 .+ 0 .j, 4 .+ 0 .j]]) <br/>


A common mistake is to call the function array() with a set of numeric arguments instead of the intended single argument in the form of a list of numbers:

Copy Source | Copy HTML<br/>>>> a = array ( 1 , 2 , 3 , 4 ) # WRONG <br/>>>> a = array ([ 1 , 2 , 3 , 4 ]) # RIGHT <br/>


The array() function is not the only function for creating arrays. Usually the elements of the array are initially unknown, and the array in which they will be stored is already needed. Therefore, there are several functions to create arrays with some kind of source content. By default, the type of array being created is float64 .

The zeros() function creates an array of zeros, and the ones() function creates an array of ones:
Copy Source | Copy HTML<br/>>>> zeros( ( 3 , 4 ) ) # <br/> array ([[ 0 ., 0 ., 0 ., 0 .],<br/> [ 0 ., 0 ., 0 ., 0 .],<br/> [ 0 ., 0 ., 0 ., 0 .]])<br/>>>> ones( ( 2 , 3 , 4 ), dtype=int16 ) # dtype <br/> array ([[[ 1 , 1 , 1 , 1 ],<br/> [ 1 , 1 , 1 , 1 ],<br/> [ 1 , 1 , 1 , 1 ]],<br/> [[ 1 , 1 , 1 , 1 ],<br/> [ 1 , 1 , 1 , 1 ],<br/> [ 1 , 1 , 1 , 1 ]]], dtype=int16) <br/>


The empty() function creates an array without filling it. The original content is random and depends on the state of the memory at the time of the array creation (that is, on the garbage stored in it):
Copy Source | Copy HTML<br/>>>> empty( ( 2 , 3 ) )<br/> array ([[ 3 .73603959e- 262 , 6 .02658058e- 154 , 6 .55490914e- 260 ],<br/> [ 5 .30498948e- 313 , 3 .14673309e- 307 , 1 .00000000e+ 000 ]])<br/>>>> empty( ( 2 , 3 ) ) # <br/> array ([[ 3 .14678735e- 307 , 6 .02658058e- 154 , 6 .55490914e- 260 ],<br/> [ 5 .30498948e- 313 , 3 .73603967e- 262 , 8 .70018275e- 313 ]]) <br/>


To create sequences of numbers, NumPy has a function similar to range() , only instead of lists, it returns arrays:
Copy Source | Copy HTML<br/>>> arange( 10 , 30 , 5 )<br/> array ([ 10 , 15 , 20 , 25 ])<br/>>>> arange( 0 , 2 , 0 . 3 )<br/> array ([ 0 . , 0 . 3 , 0 . 6 , 0 . 9 , 1 . 2 , 1 . 5 , 1 . 8 ]) <br/>


When using arange() with float arguments, it is difficult to be sure how many elements will be received (due to the limitation on the precision of floating-point numbers). Therefore, in such cases, it is usually better to use the linspace() function, which instead of a step takes a number equal to the number of necessary elements as one of the arguments:
Copy Source | Copy HTML<br/>>>> linspace( 0 , 2 , 9 ) # 9 0 2 <br/> array ([ 0 . , 0 . 25 , 0 . 5 , 0 . 75 , 1 . , 1 . 25 , 1 . 5 , 1 . 75 , 2 . ])<br/>>>> x = linspace( 0 , 2 *pi, 100 ) # <br/>>>> f = sin(x) <br/>


Array printing


When you print an array, NumPy shows them in a manner similar to nested lists, but places it a little differently:

One-dimensional arrays are displayed as rows, two-dimensional - as matrices, and three-dimensional - as matrix lists.
Copy Source | Copy HTML<br/>>>> a = arange( 6 ) # 1d array <br/>>>> print a<br/>[ 0 1 2 3 4 5 ]<br/>>>><br/>>>> b = arange( 12 ).reshape( 4 , 3 ) # 2d array <br/>>>> print b<br/>[[ 0 1 2 ]<br/> [ 3 4 5 ]<br/> [ 6 7 8 ]<br/> [ 9 10 11 ]]<br/>>>><br/>>>> c = arange( 24 ).reshape( 2 , 3 , 4 ) # 3d array <br/>>>> print c<br/>[[[ 0 1 2 3 ]<br/> [ 4 5 6 7 ]<br/> [ 8 9 10 11 ]]<br/> [[ 12 13 14 15 ]<br/> [ 16 17 18 19 ]<br/> [ 20 21 22 23 ]]] <br/>


If the array is too large to print, NumPy automatically hides the central part of the array and displays only its corners:
Copy Source | Copy HTML<br/>>>> print arange( 10000 )<br/>[ 0 1 2 ..., 9997 9998 9999 ]<br/>>>><br/>>>> print arange( 10000 ).reshape( 100 , 100 )<br/>[[ 0 1 2 ..., 97 98 99 ]<br/> [ 100 101 102 ..., 197 198 199 ]<br/> [ 200 201 202 ..., 297 298 299 ]<br/> ...,<br/> [ 9700 9701 9702 ..., 9797 9798 9799 ]<br/> [ 9800 9801 9802 ..., 9897 9898 9899 ]<br/> [ 9900 9901 9902 ..., 9997 9998 9999 ]] <br/>


If you really need to see everything that happens in a large array, displaying it in its entirety, use the set print function set_printoptions() :
Copy Source | Copy HTML<br/>>>> set_printoptions(threshold=nan) <br/>


Basic operations


Arithmetic operations on arrays are performed elementwise . A new array is created, which is filled with the results of the operator action.
Copy Source | Copy HTML<br/>>>> a = array ( [ 20 , 30 , 40 , 50 ] )<br/>>>> b = arange( 4 )<br/>>>> c = ab<br/>>>> c<br/> array ([ 20 , 29 , 38 , 47 ])<br/>>>> b** 2 <br/> array ([ 0 , 1 , 4 , 9 ])<br/>>>> 10 *sin(a)<br/> array ([ 9 . 12945251 , - 9 . 88031624 , 7 . 4511316 , - 2 . 62374854 ])<br/>>>> a< 35 <br/> array ([True, True, False, False], dtype=bool) <br/>


Unlike the matrix approach, the product * operator in the NumPy arrays also works elementwise. The matrix product can be implemented either by the dot() function, or by creating matrix objects, which will be discussed later (in the second part of the manual).
Copy Source | Copy HTML<br/>>>> A = array ( [[ 1 , 1 ],<br/>... [ 0 , 1 ]] )<br/>>>> B = array ( [[ 2 , 0 ],<br/>... [ 3 , 4 ]] )<br/>>>> A*B # <br/> array ([[ 2 , 0 ],<br/> [ 0 , 4 ]])<br/>>>> dot(A,B) # <br/> array ([[ 5 , 4 ],<br/> [ 3 , 4 ]]) <br/>


Some operations are done "on the spot", without creating a new array.
Copy Source | Copy HTML<br/>>>> a = ones(( 2 , 3 ), dtype=int)<br/>>>> b = random . random (( 2 , 3 ))<br/>>>> a *= 3 <br/>>>> a<br/> array ([[ 3 , 3 , 3 ],<br/> [ 3 , 3 , 3 ]])<br/>>>> b += a<br/>>>> b<br/> array ([[ 3 . 69092703 , 3 . 8324276 , 3 . 0114541 ],<br/> [ 3 . 18679111 , 3 . 3039349 , 3 . 37600289 ]])<br/>>>> a += b # b int <br/>>>> a<br/> array ([[ 6 , 6 , 6 ],<br/> [ 6 , 6 , 6 ]]) <br/>


When working with arrays of different types, the type of the resulting array corresponds to a more general or more accurate type.
Copy Source | Copy HTML<br/>>>> a = ones( 3 , dtype=int32)<br/>>>> b = linspace( 0 ,pi, 3 )<br/>>>> b.dtype.name<br/> 'float64' <br/>>>> c = a+b<br/>>>> c<br/> array ([ 1 . , 2 . 57079633 , 4 . 14159265 ])<br/>>>> c.dtype.name<br/> 'float64' <br/>>>> d = exp(c*1j)<br/>>>> d<br/> array ([ 0 . 54030231 + 0 .84147098j, - 0 . 84147098 + 0 .54030231j,<br/> - 0 . 54030231 - 0 .84147098j])<br/>>>> d.dtype.name<br/> 'complex128' <br/>


Many unary operations, such as calculating the sum of all elements of an array, are represented as methods of the ndarray class.
Copy Source | Copy HTML<br/>>>> a = random . random (( 2 , 3 ))<br/>>>> a<br/> array ([[ 0 . 6903007 , 0 . 39168346 , 0 . 16524769 ],<br/> [ 0 . 48819875 , 0 . 77188505 , 0 . 94792155 ]])<br/>>>> a. sum ()<br/> 3 . 4552372100521485 <br/>>>> a. min ()<br/> 0 . 16524768654743593 <br/>>>> a. max ()<br/> 0 . 9479215542670073 <br/>


By default, these operations apply to an array as if it were a list of numbers, regardless of its form. However, specifying the axis parameter, you can apply the operation on the specified axis of the array:
Copy Source | Copy HTML<br/>>>> b = arange( 12 ).reshape( 3 , 4 )<br/>>>> b<br/> array ([[ 0 , 1 , 2 , 3 ],<br/> [ 4 , 5 , 6 , 7 ],<br/> [ 8 , 9 , 10 , 11 ]])<br/>>>><br/>>>> b. sum (axis= 0 ) # <br/> array ([ 12 , 15 , 18 , 21 ])<br/>>>><br/>>>> b. min (axis= 1 ) # <br/> array ([ 0 , 4 , 8 ])<br/>>>><br/>>>> b.cumsum(axis= 1 ) # <br/> array ([[ 0 , 1 , 3 , 6 ],<br/> [ 4 , 9 , 15 , 22 ],<br/> [ 8 , 17 , 27 , 38 ]]) <br/>


Universal functions


NumPy provides work with well-known mathematical functions sin, cos, exp and so on. But in NumPy, these functions are called universal ( ufunc ). The reason for assigning such a name lies in the fact that in NumPy these functions work with arrays also elementwise, and the output is an array of values.
Copy Source | Copy HTML<br/>>>> B = arange( 3 )<br/>>>> B<br/> array ([ 0 , 1 , 2 ])<br/>>>> exp(B)<br/> array ([ 1 . , 2 . 71828183 , 7 . 3890561 ])<br/>>>> sqrt(B)<br/> array ([ 0 . , 1 . , 1 . 41421356 ])<br/>>>> C = array ([ 2 ., - 1 ., 4 .])<br/>>>> add(B, C)<br/> array ([ 2 ., 0 ., 6 .]) <br/>


Indexes, cuts, iterations


One-dimensional arrays perform indexing, slicing, and iteration operations in a very similar way to regular lists and other Python sequences.
Copy Source | Copy HTML<br/>>>> a = arange( 10 )** 3 <br/>>>> a<br/> array ([ 0 , 1 , 8 , 27 , 64 , 125 , 216 , 343 , 512 , 729 ])<br/>>>> a[ 2 ]<br/> 8 <br/>>>> a[ 2 : 5 ]<br/> array ([ 8 , 27 , 64 ])<br/>>>> a[: 6 : 2 ] = - 1000 # a <br/>>>> a<br/> array ([- 1000 , 1 , - 1000 , 27 . - 1000 , 125 , 216 , 343 , 512 , 729 ])<br/>>>> a[::- 1 ] # a <br/> array ([ 729 , 512 , 343 , 216 , 125 , - 1000 , 27 , - 1000 , 1 , - 1000 ])<br/>>>> for i in a:<br/>... print i**( 1 / 3 .),<br/>...<br/>nan 1 . 0 nan 3 . 0 nan 5 . 0 6 . 0 7 . 0 8 . 0 9 . 0 <br/>


For multidimensional arrays, there is one index per axis. Indices are transmitted as a sequence of numbers separated by commas:
Copy Source | Copy HTML<br/>>>> def f (x,y):<br/>... return 10 *x+y<br/>...<br/>>>> b = fromfunction( f ,( 5 , 4 ),dtype=int)<br/>>>> b<br/> array ([[ 0 , 1 , 2 , 3 ],<br/> [ 10 , 11 , 12 , 13 ],<br/> [ 20 , 21 , 22 , 23 ],<br/> [ 30 , 31 , 32 , 33 ],<br/> [ 40 , 41 , 42 , 43 ]])<br/>>>> b[ 2 , 3 ]<br/> 23 <br/>>>> b[:, 1 ] # b <br/> array ([ 1 , 11 , 21 , 31 , 41 ])<br/>>>> b[ 1 : 3 ,:] # b <br/> array ([[ 10 , 11 , 12 , 13 ],<br/> [ 20 , 21 , 22 , 23 ]]) <br/>


When there are fewer indexes than axes, the missing indexes are assumed to be supplemented using slices:
Copy Source | Copy HTML<br/>>>> b[- 1 ] # . b[-1,:] <br/> array ([ 40 , 41 , 42 , 43 ]) <br/>


b[i] can be read as b[i, < ':', >] . In NumPy, this can also be written using dots, like b[i, ...] .

For example, if x has rank 5 (that is, it has 5 axes), then

Copy Source | Copy HTML<br/>>>> c = array ( [ [[ 0 , 1 , 2 ], # 3d array <br/>... [ 10 , 12 , 13 ]],<br/>...<br/>... [[ 100 , 101 , 102 ],<br/>... [ 110 , 112 , 113 ]] ] )<br/>>>> c.shape<br/>( 2 , 2 , 3 )<br/>>>> c[ 1 ,...] # , c[1,:,:] c[1] <br/> array ([[ 100 , 101 , 102 ],<br/> [ 110 , 112 , 113 ]])<br/>>>> c[..., 2 ] # , c[:,:,2] <br/> array ([[ 2 , 13 ],<br/> [ 102 , 113 ]]) <br/>


Iteration of multidimensional arrays begins on the first axis:
Copy Source | Copy HTML<br/>>>> for row in b:<br/>... print row<br/>...<br/>[ 0 1 2 3 ]<br/>[ 10 11 12 13 ]<br/>[ 20 21 22 23 ]<br/>[ 30 31 32 33 ]<br/>[ 40 41 42 43 ] <br/>


However, if you need to iterate over the entire array, as if it were one-dimensional, you can use the flat attribute for this:
Copy Source | Copy HTML<br/>>>> for element in b.flat:<br/>... print element,<br/>...<br/> 0 1 2 3 10 11 12 13 20 21 22 23 30 31 32 33 40 41 42 43 <br/>


Manipulation with the form


As already mentioned, an array has a shape ( shape ), determined by the number of elements along each axis:
Copy Source | Copy HTML<br/>>>> a = floor( 10 * random . random (( 3 , 4 )))<br/>>>> a<br/> array ([[ 7 ., 5 ., 9 ., 3 .],<br/> [ 7 ., 2 ., 7 ., 8 .],<br/> [ 6 ., 8 ., 3 ., 2 .]])<br/>>>> a.shape<br/>( 3 , 4 ) <br/>


The array form can be changed using various commands:
Copy Source | Copy HTML<br/>>>> a.ravel() # <br/> array ([ 7 ., 5 ., 9 ., 3 ., 7 ., 2 ., 7 ., 8 ., 6 ., 8 ., 3 ., 2 .])<br/>>>> a.shape = ( 6 , 2 )<br/>>>> a.transpose()<br/> array ([[ 7 ., 9 ., 7 ., 7 ., 6 ., 3 .],<br/> [ 5 ., 3 ., 2 ., 8 ., 8 ., 2 .]]) <br/>


The order of the elements in the array as a result of the ravel() function corresponds to the usual “C-style”, that is, the more right the index, the “faster it changes”: the element a[0,0] follows a[0,1] . If one form of the array has been changed to another, the array is also re-formed in the “C-style”. In this order, NumPy usually creates arrays, so the ravel() function usually does not need to copy the argument, but if the array was created from slices of another array, a copy may be required. The ravel() and reshape() functions can also work (with the use of an additional argument) in the FORTRAN style, in which the more left index changes faster.

The reshape() function returns its argument with a modified form, while the resize() method modifies the array itself:
Copy Source | Copy HTML<br/>>>> a<br/> array ([[ 7 ., 5 .],<br/> [ 9 ., 3 .],<br/> [ 7 ., 2 .],<br/> [ 7 ., 8 .],<br/> [ 6 ., 8 .],<br/> [ 3 ., 2 .]])<br/>>>> a.resize(( 2 , 6 ))<br/>>>> a<br/> array ([[ 7 ., 5 ., 9 ., 3 ., 7 ., 2 .],<br/> [ 7 ., 8 ., 6 ., 8 ., 3 ., 2 .]]) <br/>


If during the operation of such a restructuring one of the arguments is specified as -1, then it is automatically calculated in accordance with the other specified:
Copy Source | Copy HTML<br/>>>> a.reshape( 3 ,- 1 )<br/> array ([[ 7 ., 5 ., 9 ., 3 .],<br/> [ 7 ., 2 ., 7 ., 8 .],<br/> [ 6 ., 8 ., 3 ., 2 .]]) <br/>


Array combining


Several arrays can be combined together along different axes:
Copy Source | Copy HTML<br/>>>> a = floor( 10 * random . random (( 2 , 2 )))<br/>>>> a<br/> array ([[ 1 ., 1 .],<br/> [ 5 ., 8 .]])<br/>>>> b = floor( 10 * random . random (( 2 , 2 )))<br/>>>> b<br/> array ([[ 3 ., 3 .],<br/> [ 6 ., 0 .]])<br/>>>> vstack((a,b))<br/> array ([[ 1 ., 1 .],<br/> [ 5 ., 8 .],<br/> [ 3 ., 3 .],<br/> [ 6 ., 0 .]])<br/>>>> hstack((a,b))<br/> array ([[ 1 ., 1 ., 3 ., 3 .],<br/> [ 5 ., 8 ., 6 ., 0 .]]) <br/>


The column_stack() function combines one-dimensional arrays as columns of a two-dimensional array:
Copy Source | Copy HTML<br/>>>> column_stack((a,b))<br/> array ([[ 1 ., 1 ., 3 ., 3 .],<br/> [ 5 ., 8 ., 6 ., 0 .]])<br/>>>> a= array ([ 4 ., 2 .])<br/>>>> b= array ([ 2 ., 8 .])<br/>>>> a[:,newaxis] # 2D- <br/> array ([[ 4 .],<br/> [ 2 .]])<br/>>>> column_stack((a[:,newaxis],b[:,newaxis]))<br/> array ([[ 4 ., 2 .],<br/> [ 2 ., 8 .]])<br/>>>> vstack((a[:,newaxis],b[:,newaxis])) # vstack <br/> array ([[ 4 .],<br/> [ 2 .],<br/> [ 2 .],<br/> [ 8 .]]) <br/>


Similarly, for rows there is a function row_stack() . For arrays with more than two axes, hstack() combines the arrays on the first axes, vstack() on the last axes, additional arguments allow you to specify the number of axes along which the union should occur.

In complex cases, r_[] and _[] can be useful, allowing you to create one-dimensional arrays using a series of numbers along one axis. They also have the ability to use ":" to specify a range of literals:

Copy Source | Copy HTML<br/>>>> r_[ 1 : 4 , 0 , 4 ]<br/> array ([ 1 , 2 , 3 , 0 , 4 ]) <br/>


Splitting one array into several smaller ones


Using hsplit() you can split an array along the horizontal axis, specifying either the number of arrays of the same shape returned, or the column numbers, after which the array is cut with scissors:
Copy Source | Copy HTML<br/>>>> a = floor( 10 * random . random (( 2 , 12 )))<br/>>>> a<br/> array ([[ 8 ., 8 ., 3 ., 9 ., 0 ., 4 ., 3 ., 0 ., 0 ., 6 ., 4 ., 4 .],<br/> [ 0 ., 3 ., 2 ., 9 ., 6 ., 0 ., 4 ., 5 ., 7 ., 5 ., 1 ., 4 .]])<br/>>>> hsplit(a, 3 ) # 3 <br/>[ array ([[ 8 ., 8 ., 3 ., 9 .],<br/> [ 0 ., 3 ., 2 ., 9 .]]), array ([[ 0 ., 4 ., 3 ., 0 .],<br/> [ 6 ., 0 ., 4 ., 5 .]]), array ([[ 0 ., 6 ., 4 ., 4 .],<br/> [ 7 ., 5 ., 1 ., 4 .]])]<br/>>>> hsplit(a,( 3 , 4 )) # a <br/>[ array ([[ 8 ., 8 ., 3 .],<br/> [ 0 ., 3 ., 2 .]]), array ([[ 9 .],<br/> [ 9 .]]), array ([[ 0 ., 4 ., 3 ., 0 ., 0 ., 6 ., 4 ., 4 .],<br/> [ 6 ., 0 ., 4 ., 5 ., 7 ., 5 ., 1 ., 4 .]])] <br/>

The vsplit() function splits an array along the vertical axis, and array_split() allows you to specify the axes along which the split will occur.

Copies and Submissions


When working with arrays, their data sometimes needs to be copied to another array, and sometimes not. This is often a source of confusion among newbies. Perhaps only three cases:

No copies at all


Simple assignment does not create a copy of the array, nor a copy of its data:
Copy Source | Copy HTML<br/>>>> a = arange( 12 )<br/>>>> b = a # <br/>>>> b is a # a b ndarray <br/>True<br/>>>> b.shape = 3 , 4 # a <br/>>>> a.shape<br/>( 3 , 4 ) <br/>


Python passes the mutable objects as references, so function calls also do not create copies:
Copy Source | Copy HTML<br/>>>> def f (x):<br/>... print id (x)<br/>...<br/>>>> id (a)<br/> 148293216 <br/>>>> f (a)<br/> 148293216 <br/>


Submission or shallow copy


Different array objects can use the same data. The view() method creates a new array object that represents the same data.

Copy Source | Copy HTML<br/>>>> c = a.view()<br/>>>> c is a<br/>False<br/>>>> c.base is a # c , a <br/>True<br/>>>> c.flags.owndata<br/>False<br/>>>><br/>>>> c.shape = 2 , 6 # <br/>>>> a.shape<br/>( 3 , 4 )<br/>>>> c[ 0 , 4 ] = 1234 # <br/>>>> a<br/> array ([[ 0 , 1 , 2 , 3 ],<br/> [ 1234 , 5 , 6 , 7 ],<br/> [ 8 , 9 , 10 , 11 ]]) <br/>


An array slice is a representation:
Copy Source | Copy HTML<br/>>>> s = a[:, 1 : 3 ]<br/>>>> s[:] = 10 # s[:] s. s=10 s[:]=10 <br/>>>> a<br/> array ([[ 0 , 10 , 10 , 3 ],<br/> [ 1234 , 10 , 10 , 7 ],<br/> [ 8 , 10 , 10 , 11 ]]) <br/>


Deep copy


The copy() method creates a real copy of the array and its data:
Copy Source | Copy HTML<br/>>>> d = a. copy () # <br/>>>> d is a<br/>False<br/>>>> d.base is a # d <br/>False<br/>>>> d[ 0 , 0 ] = 9999 <br/>>>> a<br/> array ([[ 0 , 10 , 10 , 3 ],<br/> [ 1234 , 10 , 10 , 7 ],<br/> [ 8 , 10 , 10 , 11 ]]) <br/>


Finally


So, in the first part we covered the most important basic operations of working with arrays. In addition to this part, I advise a good cheat sheet . In the second part we will talk about more specific things: about indexing with arrays of indices or boolean values, implementation of operations of linear algebra and the class of matrix and various useful tricks.

Source: https://habr.com/ru/post/121031/


All Articles