Python/Numpy
2. The Basics of Numpy Arrays
njh1008
2025. 6. 17. 09:11
Numpy Array Attributes
- We'll use Numpy's random number generator, which we will seed with a set value in order to ensure that the same random arrays are generated each time this code is run:
# In[1]
import numpy as np
rng=np.random.default_rng(seed=1701) # seed for reproducibility
x1 = rng.integers(10,size=6)
x2 = rng.integers(10,size=(3,4))
x3 = rng.integers(10,size=(3,4,5))
print("x3 ndim: ",x3.ndim)
print("x3 shape: ",x3.shape)
print("x3 size: ",x3.size)
print("x3 dtype: ",x3.dtype)
# Out[1]
x3 ndim: 3
x3 shape: (3, 4, 5)
x3 size: 60
x3 dtype: int64
Array Indexing : Accessing Single Elements
# In[2]
print(x2)
print(x2[2,-1])
# Out[2]
[[3 1 3 7]
[4 0 2 3]
[0 0 6 9]]
9
# In[3]
x2[0,0]=12
print(x2)
# Out[3]
[[12 1 3 7]
[ 4 0 2 3]
[ 0 0 6 9]]
- Unlike Python lists, Numpy array have a fixed type. For example, that if you attempt to insert a floating-point value to an integer array, the value will be truncated.
# In[4] x1[0]=3.14 print(x1)
# Out[4] [3 0 3 3 7 9]
Array Slicing : Accessing Subarrays
- Numpy slicing syntax follows that of the standard Python lists; to access a slice of an array 'x', use this:
x[start:stop:step]
One dimensional subarray
# In[5]
x=np.arange(10)
x
# Out[5]
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
# In[6]
print("first five elements:",x[:5])
print("elements after index 5:",x[5:])
print("middle subarray:",x[4:7])
print("every other element that step is 2:",x[::2])
print("every other element, starting at index 1 and step 2:",x[1::2])
print("all reversed elements:",x[::-1])
print("reversed every other element from index 5:",x[5::-2])
# Out[6]
first five elements: [0 1 2 3 4]
elements after index 5: [5 6 7 8 9]
middle subarray: [4 5 6]
every other element that step is 2: [0 2 4 6 8]
every other element, starting at index 1 and step 2: [1 3 5 7 9]
all reversed elements: [9 8 7 6 5 4 3 2 1 0]
reversed every other element from index 5: [5 3 1]
Multidimensional subarray
# In[7]
x2
# Out[7]
array([[12, 1, 3, 7],
[ 4, 0, 2, 3],
[ 0, 0, 6, 9]])
# In[8]
print("two rows, three columns:",x2[:2,:3])
print("all rows, every other column:",x2[:3,::2])
print("reversed array:",x2[::-1,::-1])
# Out[8]
two rows, three columns: [[12 1 3]
[ 4 0 2]]
all rows, every other column: [[12 3]
[ 4 2]
[ 0 6]]
reversed array: [[ 9 6 0 0]
[ 3 2 0 4]
[ 7 3 1 12]]
Accessing array rows and columns
- You can access single rows or columns of an array by combining indexing and slicing, using an empty slice marked by a single colon(:)
- However, In the case of row access, you can omit colon(:) for a more compact syntax
# In[9] print("first column of x2:",x2[:,0]) print("first row of x2:",x2[0,:]) print("equivalent to x2[0,:]:",x2[0])
# Out[9] first column of x2: [12 4 0] first row of x2: [12 1 3 7] equivalent to x2[0,:]: [12 1 3 7]
Subarrays as no-copy views
- Unlike Python list slices, Numpy array slices are returned as views rather than copies of the array data.
# In[10]
x2_sub=x2[:2,:2]
print(x2_sub)
x2_sub[0,0]=99
print(x2_sub)
print(x2)
# Out[10]
[[12 1]
[ 4 0]]
[[99 1]
[ 4 0]]
[[99 1 3 7]
[ 4 0 2 3]
[ 0 0 6 9]]
- If we modify this subarray, orginal array will be changed.
Creating copies of Arrays
- Using
copy()
method# In[11] x2_sub_copy=x2[:2,:2].copy() print(x2_sub_copy)
# Out[11] [[99 1] [ 4 0]]
# In[12]
x2_sub_copy[0,0]=42
print(x2_sub_copy)
print(x2)
# Out[12]
[[42 1]
[ 4 0]]
[[99 1 3 7]
[ 4 0 2 3]
[ 0 0 6 9]]
- If we modify this subarray, the original array is not touched.
Reshaping of Arrays
- Using
reshape()
method# In[13] grid=np.arange(1,10).reshape((3,3)) print(grid)
# Out[13] [[1 2 3] [4 5 6] [7 8 9]]
# In[14]
x=np.array([1,2,3])
print(x.reshape((1,3))) # row vector via reshape
print(x.reshape((3,1))) # column vector via reshape
# Out[14]
array([[1, 2, 3]])
array([[1],
[2],
[3]])
- A convenient shorthad for this is to use
np.newaxis
in the slicing syntax# In[15] print(x[np.newaxis,:]) # row vector via reshape print(x[:,np.newaxis]) # column vector via reshape
# Out[15] array([[1, 2, 3]]) array([[1], [2], [3]])
Array Concatenation and Splitting
Concatenation of Arrays
- Using
np.concatenate
,np.vstack(vertical stack)
,np.hstack(horizontal stack)
np.concatenate
# In[16]
x=np.array([1,2,3])
y=np.array([3,2,1])
np.concatenate([x,y])
# Out[16]
array([1, 2, 3, 3, 2, 1])
# In[17]
grid=np.array([[1,2,3],[4,5,6]])
np.concatenate([grid,grid])
# Out[17]
array([[1, 2, 3],
[4, 5, 6],
[1, 2, 3],
[4, 5, 6]])
# In[18]
np.concatenate([grid,grid],axis=1)
# Out[18]
array([[1, 2, 3, 1, 2, 3],
[4, 5, 6, 4, 5, 6]])
- For More Information about the
axis
, reference this blog: About the axis
np.vstack
# In[19]
x=np.array([1,2,3])
grid=np.array([[9,8,7],[6,5,4]])
np.vstack([x,grid])
# Out[19]
array([[1, 2, 3],
[9, 8, 7],
[6, 5, 4]])
np.hstack
# In[20]
y=np.array([[99],[99]])
np.hstack([grid,y])
# Out[20]
array([[ 9, 8, 7, 99],
[ 6, 5, 4, 99]])
Splitting of Arrays
- Using
np.split
,np.hsplit(horizontal split)
,np.vsplit(vertical split)
np.split
np.split(array,indices_or_sections,axis=0)
indices or sections
are int or 1-dimensional array- For example,
indices or sections
= [2,3]- array[:2]
- array[2:3]
- array[3:]
# In[21]
x=[1,2,3,99,99,3,2,1]
x1,x2,x3=np.split(x,[3,5])
print(x1,x2,x3)
# Out[21]
[1 2 3] [99 99] [3 2 1]
np.hsplit
- Split an array into multiple sub-arrays horizontally(column-wise)
hsplit
is equivalent to split with axis=1- The array is always split along the second axis except for 1-dimensional arrays, where it is split at axis=0
# In[22] grid=np.arange(16).reshape((4,4)) grid
# Out[22] array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11], [12, 13, 14, 15]])
# In[23]
left,right=np.hsplit(grid,2)
a=np.hsplit(grid,(2,3))
print(left)
print(right)
print(a)
# Out[23]
[[ 0 1]
[ 4 5]
[ 8 9]
[12 13]]
[[ 2 3]
[ 6 7]
[10 11]
[14 15]]
[array([[ 0, 1],
[ 4, 5],
[ 8, 9],
[12, 13]]),
array([[ 2],
[ 6],
[10],
[14]]),
array([[ 3],
[ 7],
[11],
[15]])]
With a higher dimensional array, the split is still along the second axis
# In[24] x=np.arange(8).reshape(2,2,2) a=np.hsplit(x,2) print(x) print(a)
# Out[24] [[[0 1] [2 3]] [[4 5] [6 7]]] [array([[[0, 1]], [[4, 5]]]), array([[[2, 3]], [[6, 7]]])]
With a 1-D array, the split is along the axis=0
# In[25] x=np.array([0,1,2,3,4,5]) np.hsplit(x,3)
# Out[25] [array([0, 1]), array([2, 3]), array([4, 5])]
np.vsplit
Split an array into multiple sub-arrays vertically(row-wise)
vsplit
is equivalent to split with axis=0 (default)The array is always split along the first axis regardless of the array dimension.
# In[26] upper,lower=np.vsplit(grid,2) a=np.vsplit(grid,(2,3)) print(upper) print(lower) print(a)
# Out[26] [[0 1 2 3] [4 5 6 7]] [[ 8 9 10 11] [12 13 14 15]] [array([[0, 1, 2, 3], [4, 5, 6, 7]]), array([[ 8, 9, 10, 11]]), array([[12, 13, 14, 15]])]
With a higher dimensional array, the split is still along the first axis
# In[27] x=np.arange(8).reshape(2,2,2) a=np.vsplit(x,2) print(x) print(a)
# Out[27] [[[0, 1], [2, 3]], [[4, 5], [6, 7]]] [array([[[0, 1], [2, 3]]]), array([[[4, 5], [6, 7]]])]
np.dsplit
- Split array into multiple sub-arrays along the third axis(depth) in higher-dimensional arrays.
dsplit
is equivalent to split with axis=2- The array is always split along the third axis provided the array dimension is greater than or equal to 3
# In[28]
x=np.arange(16).reshape(2,2,4)
a=np.dsplit(x,2)
b=np.dsplit(x,(2,3))
print(x)
print(a)
print(b)
# Out[28]
[[[ 0, 1, 2, 3],
[ 4, 5, 6, 7]],
[[ 8, 9, 10, 11],
[12, 13, 14, 15]]]
[array([[[ 0, 1],
[ 4, 5]],
[[ 8, 9],
[12, 13]]]),
array([[[ 2, 3],
[ 6, 7]],
[[10, 11],
[14, 15]]])
[array([[[ 0, 1],
[ 4, 5]],
[[ 8, 9],
[12, 13]]]),
array([[[ 2],
[ 6]],
[[10],
[14]]]),
array([[[ 3],
[ 7]],
[[11],
[15]]])]