<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Tutorial Brief
numpy is a powerful set of tools to perform mathematical operations of on lists of numbers. It works faster than normal python lists operations and can manupilate high dimentional arrays too.
Finding Help
Step1:  Working with ndarray
We will generate an ndarray with np.arange method.
np.arange([start,] stop[, step,], dtype=None)
Step2:  Examining ndrray
Step3:  Why to use numpy?
We will compare the time it takes to create two lists and do some basic operations on them.
Generate a list
Step4:  Basic Operation
Step5:  Most Common Functions
List Creation
array(object, dtype=None, copy=True, order=None, subok=False, ndmin=0)
```
Parameters
object 
Step6:  Multi Dimentional Array
Step7:  zeros(shape, dtype=float, order='C') and ones(shape, dtype=float, order='C')
```
Parameters
shape 
Step8:  np.linspace(start, stop, num=50, endpoint=True, retstep=False)
```
Parameters
start 
Step9:  random_sample(size=None)
```
Parameters
size 
Step10:  Statistical Analysis
Step11:  np.max(a, axis=None, out=None, keepdims=False)
```
Parameters
a 
Step12:  np.min(a, axis=None, out=None, keepdims=False)
Step13:  np.mean(a, axis=None, dtype=None, out=None, keepdims=False)
Step14:  np.median(a, axis=None, out=None, overwrite_input=False)
Step15:  np.std(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False)
Step16:  np.sum(a, axis=None, dtype=None, out=None, keepdims=False)
Step17:  Reshaping
np.reshape(a, newshape, order='C')
Step18:  np.ravel(a, order='C')
Step19:  Slicing
Step20:  Slicing a range
Step21:  Stepping
Step22:  Matrix Operations
Step23:  Addition
Step24:  Subtraction
Step25:  Multiplication (Element by Element)
Step26:  Multiplication (Matrix Multiplication)
Step27:  Division
Step28:  Square
Step29:  Power
Step30:  Transpose
Step31:  Inverse
<ASSISTANT_TASK:>
Python Code:
import numpy as np
Explanation: Tutorial Brief
numpy is a powerful set of tools to perform mathematical operations of on lists of numbers. It works faster than normal python lists operations and can manupilate high dimentional arrays too.
Finding Help:
http://wiki.scipy.org/Tentative_NumPy_Tutorial
http://docs.scipy.org/doc/numpy/reference/
SciPy (pronounced “Sigh Pie”) is a Python-based ecosystem of open-source software for mathematics, science, and engineering.
http://www.scipy.org/
So NumPy is a part of a bigger ecosystem of libraries that build on the optimized performance of NumPy NDArray.
It contain these core packages:
<table>
<tr>
    <td style="background:Lavender;"><img src="http://www.scipy.org/_static/images/numpylogo_med.png"  style="width:50px;height:50px;" /></td>
    <td style="background:Lavender;"><h4>NumPy</h4> Base N-dimensional array package </td>
    <td><img src="http://www.scipy.org/_static/images/scipy_med.png" style="width:50px;height:50px;" /></td>
    <td><h4>SciPy</h4> Fundamental library for scientific computing </td>
    <td><img src="http://www.scipy.org/_static/images/matplotlib_med.png" style="width:50px;height:50px;" /></td>
    <td><h4>Matplotlib</h4> Comprehensive 2D Plotting </td>
</tr>
<tr>
    <td><img src="http://www.scipy.org/_static/images/ipython.png" style="width:50px;height:50px;" /></td>
    <td><h4>IPython</h4> Enhanced Interactive Console </td>
    <td><img src="http://www.scipy.org/_static/images/sympy_logo.png" style="width:50px;height:50px;" /></td>
    <td><h4>SymPy</h4> Symbolic mathematics </td>
    <td><img src="http://www.scipy.org/_static/images/pandas_badge2.jpg" style="width:50px;height:50px;" /></td>
    <td><h4>Pandas</h4> Data structures & analysis </td>
</tr>
</table>
Importig the library
Import numpy library as np
This helps in writing code and it's almost a standard in scientific work
End of explanation
np.arange(10)
np.arange(1,10)
np.arange(1,10, 0.5)
np.arange(1,10, 3)
np.arange(1,10, 2, dtype=np.float64)
Explanation: Working with ndarray
We will generate an ndarray with np.arange method.
np.arange([start,] stop[, step,], dtype=None)
End of explanation
ds = np.arange(1,10,2)
ds.ndim
ds.shape
ds.size
ds.dtype
ds.itemsize
x=ds.data
list(x)
ds
# Memory Usage
ds.size * ds.itemsize
Explanation: Examining ndrray
End of explanation
%%capture timeit_results
# Regular Python
%timeit python_list_1 = range(1,1000)
python_list_1 = range(1,1000)
python_list_2 = range(1,1000)
#Numpy
%timeit numpy_list_1 = np.arange(1,1000)
numpy_list_1 = np.arange(1,1000)
numpy_list_2 = np.arange(1,1000)
print timeit_results
# Function to calculate time in seconds
def return_time(timeit_result):
    temp_time = float(timeit_result.split(" ")[5])
    temp_unit = timeit_result.split(" ")[6]
    if temp_unit == "ms":
        temp_time = temp_time * 1e-3
    elif temp_unit == "us":
        temp_time = temp_time * 1e-6
    elif temp_unit == "ns":
        temp_time = temp_time * 1e-9
    return temp_time
python_time = return_time(timeit_results.stdout.split("\n")[0])
numpy_time = return_time(timeit_results.stdout.split("\n")[1])
print "Python/NumPy: %.1f" % (python_time/numpy_time)
Explanation: Why to use numpy?
We will compare the time it takes to create two lists and do some basic operations on them.
Generate a list
End of explanation
%%capture timeit_python
%%timeit
# Regular Python
[(x + y) for x, y in zip(python_list_1, python_list_2)]
[(x - y) for x, y in zip(python_list_1, python_list_2)]
[(x * y) for x, y in zip(python_list_1, python_list_2)]
[(x / y) for x, y in zip(python_list_1, python_list_2)];
print timeit_python
%%capture timeit_numpy
%%timeit
#Numpy
numpy_list_1 + numpy_list_2
numpy_list_1 - numpy_list_2
numpy_list_1 * numpy_list_2
numpy_list_1 / numpy_list_2;
print timeit_numpy
python_time = return_time(timeit_python.stdout)
numpy_time = return_time(timeit_numpy.stdout)
print "Python/NumPy: %.1f" % (python_time/numpy_time)
Explanation: Basic Operation
End of explanation
np.array([1,2,3,4,5])
Explanation: Most Common Functions
List Creation
array(object, dtype=None, copy=True, order=None, subok=False, ndmin=0)
```
Parameters
object : array_like
    An array, any object exposing the array interface, an
    object whose array method returns an array, or any
    (nested) sequence.
dtype : data-type, optional
    The desired data-type for the array.  If not given, then
    the type will be determined as the minimum type required
    to hold the objects in the sequence.  This argument can only
    be used to 'upcast' the array.  For downcasting, use the
    .astype(t) method.
copy : bool, optional
    If true (default), then the object is copied.  Otherwise, a copy
    will only be made if array returns a copy, if obj is a
    nested sequence, or if a copy is needed to satisfy any of the other
    requirements (dtype, order, etc.).
order : {'C', 'F', 'A'}, optional
    Specify the order of the array.  If order is 'C' (default), then the
    array will be in C-contiguous order (last-index varies the
    fastest).  If order is 'F', then the returned array
    will be in Fortran-contiguous order (first-index varies the
    fastest).  If order is 'A', then the returned array may
    be in any order (either C-, Fortran-contiguous, or even
    discontiguous).
subok : bool, optional
    If True, then sub-classes will be passed-through, otherwise
    the returned array will be forced to be a base-class array (default).
ndmin : int, optional
    Specifies the minimum number of dimensions that the resulting
    array should have.  Ones will be pre-pended to the shape as
    needed to meet this requirement.
```
End of explanation
np.array([[1,2],[3,4],[5,6]])
Explanation: Multi Dimentional Array
End of explanation
np.zeros((3,4))
np.zeros((3,4), dtype=np.int64)
np.ones((3,4))
Explanation: zeros(shape, dtype=float, order='C') and ones(shape, dtype=float, order='C')
```
Parameters
shape : int or sequence of ints
    Shape of the new array, e.g., (2, 3) or 2.
dtype : data-type, optional
    The desired data-type for the array, e.g., numpy.int8.  Default is
    numpy.float64.
order : {'C', 'F'}, optional
    Whether to store multidimensional data in C- or Fortran-contiguous
    (row- or column-wise) order in memory.
```
End of explanation
np.linspace(1,5)
np.linspace(0,2,num=4)
np.linspace(0,2,num=4,endpoint=False)
Explanation: np.linspace(start, stop, num=50, endpoint=True, retstep=False)
```
Parameters
start : scalar
    The starting value of the sequence.
stop : scalar
    The end value of the sequence, unless endpoint is set to False.
    In that case, the sequence consists of all but the last of num + 1
    evenly spaced samples, so that stop is excluded.  Note that the step
    size changes when endpoint is False.
num : int, optional
    Number of samples to generate. Default is 50.
endpoint : bool, optional
    If True, stop is the last sample. Otherwise, it is not included.
    Default is True.
retstep : bool, optional
    If True, return (samples, step), where step is the spacing
    between samples.
```
End of explanation
np.random.random((2,3))
np.random.random_sample((2,3))
Explanation: random_sample(size=None)
```
Parameters
size : int or tuple of ints, optional
    Defines the shape of the returned array of random floats. If None
    (the default), returns a single float.
```
End of explanation
data_set = np.random.random((2,3))
data_set
Explanation: Statistical Analysis
End of explanation
np.max(data_set)
np.max(data_set, axis=0)
np.max(data_set, axis=1)
Explanation: np.max(a, axis=None, out=None, keepdims=False)
```
Parameters
a : array_like
    Input data.
axis : int, optional
    Axis along which to operate.  By default, flattened input is used.
out : ndarray, optional
    Alternative output array in which to place the result.  Must
    be of the same shape and buffer length as the expected output.
    See doc.ufuncs (Section "Output arguments") for more details.
keepdims : bool, optional
    If this is set to True, the axes which are reduced are left
    in the result as dimensions with size one. With this option,
    the result will broadcast correctly against the original arr.
```
End of explanation
np.min(data_set)
Explanation: np.min(a, axis=None, out=None, keepdims=False)
End of explanation
np.mean(data_set)
Explanation: np.mean(a, axis=None, dtype=None, out=None, keepdims=False)
End of explanation
np.median(data_set)
Explanation: np.median(a, axis=None, out=None, overwrite_input=False)
End of explanation
np.std(data_set)
Explanation: np.std(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False)
End of explanation
np.sum(data_set)
Explanation: np.sum(a, axis=None, dtype=None, out=None, keepdims=False)
End of explanation
np.reshape(data_set, (3,2))
np.reshape(data_set, (6,1))
np.reshape(data_set, (6))
Explanation: Reshaping
np.reshape(a, newshape, order='C')
End of explanation
np.ravel(data_set)
Explanation: np.ravel(a, order='C')
End of explanation
data_set = np.random.random((5,10))
data_set
data_set[1]
data_set[1][0]
data_set[1,0]
Explanation: Slicing
End of explanation
data_set[2:4]
data_set[2:4,0]
data_set[2:4,0:2]
data_set[:,0]
Explanation: Slicing a range
End of explanation
data_set[2:4:1]
data_set[::]
data_set[::2]
data_set[2:4]
data_set[2:4,::2]
Explanation: Stepping
End of explanation
import numpy as np
# Matrix A 
A = np.array([[1,2],[3,4]])
# Matrix B
B = np.array([[3,4],[5,6]])
Explanation: Matrix Operations
End of explanation
A+B
Explanation: Addition
End of explanation
A-B
Explanation: Subtraction
End of explanation
A*B
Explanation: Multiplication (Element by Element)
End of explanation
A.dot(B)
Explanation: Multiplication (Matrix Multiplication)
End of explanation
A/B
Explanation: Division
End of explanation
np.square(A)
Explanation: Square
End of explanation
np.power(A,3) #cube of matrix
Explanation: Power
End of explanation
A.transpose()
Explanation: Transpose
End of explanation
np.linalg.inv(A)
Explanation: Inverse
End of explanation
<END_TASK>