Numpy¶
Array¶
An array is a fundamental data structure in programming, used for storing a collection of elements (values or variables), typically of the same data type, in an ordered sequence. It can be thought of as a contiguous block of memory where each element is identified by one or more indices.
Key Characteristics of an Array:
- Fixed Size: Arrays are typically of a fixed size, determined at the time of creation.
- Homogeneous Elements: All elements in an array are of the same data type.
- Indexed: Each element in an array is accessed by its index. In most programming languages, array indexing starts at 0.
- Contiguous Memory Allocation: Arrays allocate memory in contiguous memory locations, ensuring efficient access to elements.
In [1]:
Copied!
import numpy as np
import numpy as np
In [2]:
Copied!
print(np.eye(4))
print(np.eye(4))
[[1. 0. 0. 0.] [0. 1. 0. 0.] [0. 0. 1. 0.] [0. 0. 0. 1.]]
In [3]:
Copied!
### Create array
### numpy.array(object, dtype = None, copy = True, ndmin = 0)
np.array([1.,2.,3.])
### Create array
### numpy.array(object, dtype = None, copy = True, ndmin = 0)
np.array([1.,2.,3.])
Out[3]:
array([1., 2., 3.])
In [4]:
Copied!
np.array([[1.,2.,3.],[4,5,6]])
np.array([[1.,2.,3.],[4,5,6]])
Out[4]:
array([[1., 2., 3.], [4., 5., 6.]])
In [5]:
Copied!
np.array([1,2,3],dtype=np.float32)
np.array([1,2,3],dtype=np.float32)
Out[5]:
array([1., 2., 3.], dtype=float32)
In [6]:
Copied!
np.array([[1.,2.,3.],[4,5,6]],ndmin = 3)
np.array([[1.,2.,3.],[4,5,6]],ndmin = 3)
Out[6]:
array([[[1., 2., 3.], [4., 5., 6.]]])
In [7]:
Copied!
np.empty([4,3],dtype= int)
np.empty([4,3],dtype= int)
Out[7]:
array([[ 0, 1072693248, 0], [1073741824, 0, 1074266112], [ 0, 1074790400, 0], [1075052544, 0, 1075314688]])
In [8]:
Copied!
np.zeros([4,3])
np.zeros([4,3])
Out[8]:
array([[0., 0., 0.], [0., 0., 0.], [0., 0., 0.], [0., 0., 0.]])
In [9]:
Copied!
np.ones([4,3])
np.ones([4,3])
Out[9]:
array([[1., 1., 1.], [1., 1., 1.], [1., 1., 1.], [1., 1., 1.]])
In [10]:
Copied!
np.full([2,4,3],4)
np.full([2,4,3],4)
Out[10]:
array([[[4, 4, 4], [4, 4, 4], [4, 4, 4], [4, 4, 4]], [[4, 4, 4], [4, 4, 4], [4, 4, 4], [4, 4, 4]]])
In [11]:
Copied!
### np.arange(start,stop,step,dtype = None)
### np.linspace(start,stop,num = 50, endpoint=True,retstep = False,dtype = None)
### np.logspace(start,stop,num = 50, endpoint=True,base=10.0, dtype = None)
np.arange(1,11,2)
### np.arange(start,stop,step,dtype = None)
### np.linspace(start,stop,num = 50, endpoint=True,retstep = False,dtype = None)
### np.logspace(start,stop,num = 50, endpoint=True,base=10.0, dtype = None)
np.arange(1,11,2)
Out[11]:
array([1, 3, 5, 7, 9])
if you set retstep=True
, np.linspace()
will return a tuple containing two elements:
- The array of evenly spaced values.
- The step size, which is the difference between each value in the array.
In [12]:
Copied!
np.linspace(1,11,5,retstep=True)
np.linspace(1,11,5,retstep=True)
Out[12]:
(array([ 1. , 3.5, 6. , 8.5, 11. ]), 2.5)
In [13]:
Copied!
np.logspace(0,23,23,base = 2)
np.logspace(0,23,23,base = 2)
Out[13]:
array([1.00000000e+00, 2.06401656e+00, 4.26016436e+00, 8.79304978e+00, 1.81490004e+01, 3.74598373e+01, 7.73177244e+01, 1.59585064e+02, 3.29386214e+02, 6.79858600e+02, 1.40323941e+03, 2.89630938e+03, 5.97803051e+03, 1.23387540e+04, 2.54673925e+04, 5.25651199e+04, 1.08495278e+05, 2.23936050e+05, 4.62207716e+05, 9.54004380e+05, 1.96908084e+06, 4.06421545e+06, 8.38860800e+06])
Random Number¶
np.random.rand()
: [0-1)np.random.randn()
: normal distributionnp.random.randint()
: with given rangenp.random.normal()
In [14]:
Copied!
np.random.rand(5)
np.random.rand(5)
Out[14]:
array([0.04012504, 0.93882052, 0.10541024, 0.80328963, 0.35380446])
In [15]:
Copied!
np.random.rand(2,3)
np.random.rand(2,3)
Out[15]:
array([[0.31956563, 0.63627817, 0.42364336], [0.64642179, 0.13677649, 0.97706831]])
In [16]:
Copied!
np.random.randn(3,4)
np.random.randn(3,4)
Out[16]:
array([[-2.44137449, -0.16770902, 0.03237436, 0.46901236], [-0.32862965, -0.56243853, 0.50797587, -0.30136115], [ 0.07688783, -1.25779286, 0.75431792, -1.37443687]])
In [17]:
Copied!
np.random.randint(1,20,size=(2,3))
np.random.randint(1,20,size=(2,3))
Out[17]:
array([[6, 1, 4], [3, 6, 5]])
In [18]:
Copied!
np.random.normal(0,5,size=(2,3))
np.random.normal(0,5,size=(2,3))
Out[18]:
array([[-1.44812829, 6.62458314, 2.50280433], [-0.62043576, 2.82744051, -4.23102983]])
In [19]:
Copied!
np.asarray([1,2,3])
np.asarray([1,2,3])
Out[19]:
array([1, 2, 3])
In [20]:
Copied!
np.asarray([(1,2,3),(4,5,6)])
np.asarray([(1,2,3),(4,5,6)])
Out[20]:
array([[1, 2, 3], [4, 5, 6]])
In [21]:
Copied!
np.asarray([[1,2,3],[4,5,6]])
np.asarray([[1,2,3],[4,5,6]])
Out[21]:
array([[1, 2, 3], [4, 5, 6]])
Dynamic array¶
np.frombuffer()
: is used to create a one-dimensional array from a buffer object, like a byte array or a buffer-like object.- Buffer Object: The buffer object can be any object that exposes the buffer interface, such as bytes, bytearray, or memoryview.
- Data Type (dtype): You can specify the data type of the resulting array. If not specified, the default data type is float.
np.fromiter()
: creates a new one-dimensional array from an iterable object.- Iterable Input: The first argument to `np.fromiter`` must be an iterable object, like a generator or an iterator.
- Data Type (dtype): You must specify the data type of the resulting array with the dtype parameter. Unlike some other NumPy functions, dtype is not optional for `np.fromiter`` because the function cannot infer the data type from the iterable.
- Size (count): You can optionally specify the number of items to read from the iterator. If not specified, np.fromiter will consume the iterator until it is exhausted.
np.empty_like()
: create a new array with the same shape and type as a given array, but without initializing the entries.- Same Shape and Type: The new array has the same shape and data type as the input array.
np.zeros_like()
np.ones_like()
np.full_like()
In [22]:
Copied!
buffer = b'\x01\x02\x03\x04' # A simple byte buffer
array = np.frombuffer(buffer, dtype=np.uint8) # Create a NumPy array with unsigned byte type
print(array)
buffer = b'\x01\x02\x03\x04' # A simple byte buffer
array = np.frombuffer(buffer, dtype=np.uint8) # Create a NumPy array with unsigned byte type
print(array)
[1 2 3 4]
In [23]:
Copied!
# Define a generator that yields squared numbers
def gen():
for i in range(10):
yield i ** 2
# Create a NumPy array from the generator
array = np.fromiter(gen(), dtype=int)
print(array)
# Define a generator that yields squared numbers
def gen():
for i in range(10):
yield i ** 2
# Create a NumPy array from the generator
array = np.fromiter(gen(), dtype=int)
print(array)
[ 0 1 4 9 16 25 36 49 64 81]
In [24]:
Copied!
# Create an existing array
a = np.array([[1, 2, 3], [4, 5, 6]])
# Create a new array with the same shape and type as 'a'
b = np.empty_like(a)
print(b)
# Create an existing array
a = np.array([[1, 2, 3], [4, 5, 6]])
# Create a new array with the same shape and type as 'a'
b = np.empty_like(a)
print(b)
[[-1954833600 363 0] [ 0 131074 537538168]]
In [25]:
Copied!
np.zeros_like(a)
np.zeros_like(a)
Out[25]:
array([[0, 0, 0], [0, 0, 0]])
In [26]:
Copied!
np.ones_like(a)
np.ones_like(a)
Out[26]:
array([[1, 1, 1], [1, 1, 1]])
In [27]:
Copied!
np.full_like(a,8)
np.full_like(a,8)
Out[27]:
array([[8, 8, 8], [8, 8, 8]])
Data Type¶
Integer Types:
int8
,int16
,int32
,int64
: These represent integer numbers of different sizes (8, 16, 32, and 64 bits respectively).uint8
,uint16
,uint32
,uint64
: Unsigned integer types, which represent only non-negative integers of various sizes.
Floating Point Types:
float16
,float32
,float64
,float128
: Floating point numbers with varying levels of precision, where the number represents the number of bits used.
Complex Number Types:
complex64
,complex128
,complex256
: These types are for complex numbers, with floating point numbers representing the real and imaginary parts. The numbers 64, 128, and 256 indicate the total size of each number in bits.
Boolean Type:
bool
: Represents Boolean values (True or False).
Object Type:
object
: Can hold objects, allowing for arrays of mixed types, but should be used sparingly due to performance implications.
String Types:
string_
,unicode_
: Fixed-size string types, where each element of the array is a string of the same length. unicode_ is for Unicode strings.
Fixed Size Types:
byte
: Represents a single byte.void
: Represents a fixed-size chunk of memory for other types, useful for creating arrays with fields (similar to structs in C).
Operation in Array¶
In [29]:
Copied!
array1 = np.array([1,2,3])
array2 = np.array([4,5,6])
array1 + array2 , array2 - array1
array1 = np.array([1,2,3])
array2 = np.array([4,5,6])
array1 + array2 , array2 - array1
Out[29]:
(array([5, 7, 9]), array([3, 3, 3]))
In [30]:
Copied!
array1 * array2 , array2 / array1
array1 * array2 , array2 / array1
Out[30]:
(array([ 4, 10, 18]), array([4. , 2.5, 2. ]))
In [31]:
Copied!
array1 > array2,array1 != array2
array1 > array2,array1 != array2
Out[31]:
(array([False, False, False]), array([ True, True, True]))
Index and slice¶
In [35]:
Copied!
array1 = np.random.rand(100)
array1[5:10:2]
array1 = np.random.rand(100)
array1[5:10:2]
Out[35]:
array([0.74948103, 0.70512509, 0.03720135])
In [36]:
Copied!
array1[5:10]
array1[5:10]
Out[36]:
array([0.74948103, 0.88394099, 0.70512509, 0.69645815, 0.03720135])
In [38]:
Copied!
array1 = np.array([[1,2,3,4],[5,6,7,8]])
array1[1][2],array1[1,2]
array1 = np.array([[1,2,3,4],[5,6,7,8]])
array1[1][2],array1[1,2]
Out[38]:
(7, 7)
In [40]:
Copied!
array1[::]
array1[::]
Out[40]:
array([[1, 2, 3, 4], [5, 6, 7, 8]])
In [43]:
Copied!
array1[::-1]
array1[::-1]
Out[43]:
array([[5, 6, 7, 8], [1, 2, 3, 4]])
In [45]:
Copied!
### Difference between numpy array and list
print(array1)
arr1 = array1[1]
print(arr1)
arr1[1] = 99
print(array1)
### Difference between numpy array and list
print(array1)
arr1 = array1[1]
print(arr1)
arr1[1] = 99
print(array1)
[[1 2 3 4] [5 6 7 8]] [5 6 7 8] [[ 1 2 3 4] [ 5 99 7 8]]
In [47]:
Copied!
lst = [10,20,30,40]
lst1 = lst[1:3]
lst1[1] = 99
lst1,lst
lst = [10,20,30,40]
lst1 = lst[1:3]
lst1[1] = 99
lst1,lst
Out[47]:
([20, 99], [10, 20, 30, 40])
reshapre
and transpose
¶
In [55]:
Copied!
arr = np.arange(1,13).reshape(3,4)
print(arr)
print(arr[1,2])
print(arr[:,2])
print(arr[2,:])
arr = np.arange(1,13).reshape(3,4)
print(arr)
print(arr[1,2])
print(arr[:,2])
print(arr[2,:])
[[ 1 2 3 4] [ 5 6 7 8] [ 9 10 11 12]] 7 [ 3 7 11] [ 9 10 11 12]
In [58]:
Copied!
arr = np.arange(24).reshape(4,6)
arr
arr = np.arange(24).reshape(4,6)
arr
Out[58]:
array([[ 0, 1, 2, 3, 4, 5], [ 6, 7, 8, 9, 10, 11], [12, 13, 14, 15, 16, 17], [18, 19, 20, 21, 22, 23]])
In [59]:
Copied!
arr.T
arr.T
Out[59]:
array([[ 0, 6, 12, 18], [ 1, 7, 13, 19], [ 2, 8, 14, 20], [ 3, 9, 15, 21], [ 4, 10, 16, 22], [ 5, 11, 17, 23]])
In [60]:
Copied!
arr.transpose()
arr.transpose()
Out[60]:
array([[ 0, 6, 12, 18], [ 1, 7, 13, 19], [ 2, 8, 14, 20], [ 3, 9, 15, 21], [ 4, 10, 16, 22], [ 5, 11, 17, 23]])
Delete and Add elements¶
In [64]:
Copied!
n1 = np.array([[1,2],[3,4],[5,6]])
print(n1)
np.delete(n1,2,axis=0)
np.delete(n1,1,axis=1)
n1 = np.array([[1,2],[3,4],[5,6]])
print(n1)
np.delete(n1,2,axis=0)
np.delete(n1,1,axis=1)
[[1 2] [3 4] [5 6]]
Out[64]:
array([[1], [3], [5]])
In [65]:
Copied!
print(n1)
n1[1] = [30,40]
print(n1)
print(n1)
n1[1] = [30,40]
print(n1)
[[1 2] [3 4] [5 6]] [[ 1 2] [30 40] [ 5 6]]
In [67]:
Copied!
n = np.arange(1,11)
n[np.where(n > 5)]
n = np.arange(1,11)
n[np.where(n > 5)]
Out[67]:
array([ 6, 7, 8, 9, 10])
In [69]:
Copied!
n3 = np.where(n>5,2,0)
n3
n3 = np.where(n>5,2,0)
n3
Out[69]:
array([0, 0, 0, 0, 0, 2, 2, 2, 2, 2])
In [70]:
Copied!
[0 if x <5 else 2 for x in n]
[0 if x <5 else 2 for x in n]
Out[70]:
[0, 0, 0, 0, 2, 2, 2, 2, 2, 2]