import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
//anaconda/lib/python2.7/site-packages/matplotlib/font_manager.py:273: UserWarning: Matplotlib is building the font cache using fc-list. This may take a moment.
warnings.warn('Matplotlib is building the font cache using fc-list. This may take a moment.')
%matplotlib inline
The same broadcsting rule governing arithmetic operations also applies to setting values via array indexing.
from pandas import DataFrame,Series
arr = np.zeros((4,3))
arr[:] = 5
arr
array([[ 5., 5., 5.],
[ 5., 5., 5.],
[ 5., 5., 5.],
[ 5., 5., 5.]])
However, if we had a one-dimentional array of values we wanted to set into the columns of the array,we can do that as long as the shape is compatible:
While many NumPy users will only make use of the fast element-wise operations pro- vided by the universal functions, there are a number of additional features that occa- sionally can help you write more concise code without loops.
Each of NumPy’s binary ufuncs has special methods for performing certain kinds of special vectorized operations.
Method | Description |
---|---|
reduce(x) | Aggregate values by successive applications of the operation |
accumulate(x) | Aggregate values, preserving all partial aggregates |
reduceat(x, bins) | “Local” reduce or “group by”. Reduce contiguous slices of data to produce aggregated array. |
outer(x, y) | Apply operation to all pairs of elements in x and y. Result array has shape x.shape + y.shape |
reduce
takes a single array and aggregates its values, optionally along an axis, by performing a sequence of binary operations.
For example, an alternate way to sum elements in an array is to use np.add.reduce:
arr = np.arange(10)
np.add.reduce(arr)
45
np.sum(arr)
45
a less trivial example
use np.logical_and to check whether the values in each row of an array are sorted:
arr = np.random.randn(5, 5)
arr[::2].sort(1)
np.sort
arr
array([[ -1.58645456e+00, -1.36502511e+00, -5.41627950e-04,
4.86430078e-01, 1.17172633e+00],
[ -7.44597469e-01, -4.24979151e-01, -2.24296763e+00,
3.15071902e-01, 9.84530055e-01],
[ -1.54861818e+00, -3.99856553e-01, -1.67025551e-01,
8.91978379e-02, 1.31957741e+00],
[ 4.00996840e-01, -2.38865213e-03, 1.70717270e-01,
-9.66816316e-01, 3.94653542e-01],
[ -1.46761823e+00, -8.56722218e-01, -5.79742413e-01,
2.53720291e-01, 2.97676083e+00]])
arr[:,:-1]
array([[ -1.58645456e+00, -1.36502511e+00, -5.41627950e-04,
4.86430078e-01],
[ -7.44597469e-01, -4.24979151e-01, -2.24296763e+00,
3.15071902e-01],
[ -1.54861818e+00, -3.99856553e-01, -1.67025551e-01,
8.91978379e-02],
[ 4.00996840e-01, -2.38865213e-03, 1.70717270e-01,
-9.66816316e-01],
[ -1.46761823e+00, -8.56722218e-01, -5.79742413e-01,
2.53720291e-01]])
arr[:,1:]
array([[ -1.36502511e+00, -5.41627950e-04, 4.86430078e-01,
1.17172633e+00],
[ -4.24979151e-01, -2.24296763e+00, 3.15071902e-01,
9.84530055e-01],
[ -3.99856553e-01, -1.67025551e-01, 8.91978379e-02,
1.31957741e+00],
[ -2.38865213e-03, 1.70717270e-01, -9.66816316e-01,
3.94653542e-01],
[ -8.56722218e-01, -5.79742413e-01, 2.53720291e-01,
2.97676083e+00]])
arr[:,:-1] < arr[:,1:]
array([[ True, True, True, True],
[ True, False, True, True],
[ True, True, True, True],
[False, True, False, True],
[ True, True, True, True]], dtype=bool)
np.logical_and.reduce(arr[:,:-1] < arr[:,1:], axis=1)
array([ True, False, True, False, True], dtype=bool)
arr[::2]
array([[ -1.58645456e+00, -1.36502511e+00, -5.41627950e-04,
4.86430078e-01, 1.17172633e+00],
[ -1.54861818e+00, -3.99856553e-01, -1.67025551e-01,
8.91978379e-02, 1.31957741e+00],
[ -1.46761823e+00, -8.56722218e-01, -5.79742413e-01,
2.53720291e-01, 2.97676083e+00]])
accumulate is related to reduce like cumsum is related to sum. It produces an array of the
same size with the intermediate “accumulated” values:
arr = np.arange(15).reshape((3,5))
np.add.accumulate(arr, axis=1)
array([[ 0, 1, 3, 6, 10],
[ 5, 11, 18, 26, 35],
[10, 21, 33, 46, 60]])
outer performs a pairwise cross-product between two arrays:
arr = np.arange(3).repeat([1,2,3])
arr
array([0, 1, 1, 2, 2, 2])
np.multiply.outer(arr, np.arange(5))
array([[0, 0, 0, 0, 0],
[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4],
[0, 2, 4, 6, 8],
[0, 2, 4, 6, 8],
[0, 2, 4, 6, 8]])
np.multiply.outer
Apply the ufunc op
to all pairs (a, b) with a in A
and b in B
.
result = np.subtract.outer(np.random.randn(3,4),np.random.randn(5))
result
array([[[-1.54216517, -0.52986349, -1.34379847, -2.32636464, -2.53081338],
[-0.32168391, 0.69061777, -0.12331721, -1.10588338, -1.31033212],
[ 1.00529622, 2.0175979 , 1.20366292, 0.22109675, 0.01664801],
[ 1.02270583, 2.0350075 , 1.22107253, 0.23850636, 0.03405762]],
[[ 2.18387989, 3.19618157, 2.38224659, 1.39968042, 1.19523168],
[-0.36959033, 0.64271135, -0.17122363, -1.1537898 , -1.35823854],
[ 0.49572124, 1.50802291, 0.69408793, -0.28847823, -0.49292697],
[-3.38464023, -2.37233855, -3.18627353, -4.1688397 , -4.37328844]],
[[-0.28755193, 0.72474974, -0.08918523, -1.0717514 , -1.27620014],
[-0.99607282, 0.01622886, -0.79770612, -1.78027229, -1.98472103],
[ 0.57069522, 1.5829969 , 0.76906192, -0.21350425, -0.41795299],
[ 0.70100281, 1.71330448, 0.8993695 , -0.08319666, -0.2876454 ]]])
The last method, reduceat, performs a “local reduce”, in essence an array groupby operation in which slices of the array are aggregated together. While it’s less flexible than the GroupBy capabilities in pandas, it can be very fast and powerful in the right circumstances. It accepts a sequence of “bin edges” which indicate how to split and aggregate the values:
np.add.reduceat
arr = np.arange(8)
arr[::2]
array([0, 2, 4, 6])
np.add.reduceat(arr, [1,5,6,2])
array([10, 5, 6, 27])
arr = np.multiply.outer(np.arange(4), np.arange(5))
arr
array([[ 0, 0, 0, 0, 0],
[ 0, 1, 2, 3, 4],
[ 0, 2, 4, 6, 8],
[ 0, 3, 6, 9, 12]])
np.add.reduceat(arr, [0, 2, 4], axis=1)
array([[ 0, 0, 0],
[ 1, 5, 4],
[ 2, 10, 8],
[ 3, 15, 12]])
User Function
Docstring:
frompyfunc(func, nin, nout)
Takes an arbitrary Python function and returns a Numpy ufunc.
Can be used, for example, to add broadcasting to a built-in Python
function (see Examples section).
Parameters | name |
---|---|
func : Python function object | An arbitrary Python function. |
nin : int | The number of input arguments. |
nout : int | The number of objects returned by func . |
out : ufunc
Returns a Numpy universal function (ufunc
) object.
The returned ufunc always returns PyObject arrays.
Use frompyfunc to add broadcasting to the Python function oct
:
>>> oct_array = np.frompyfunc(oct, 1, 1)
>>> oct_array(np.array((10, 30, 100)))
array([012, 036, 0144], dtype=object)
>>> np.array((oct(10), oct(30), oct(100))) # for comparison
array(['012', '036', '0144'],
dtype='|S4')
Type: builtin_function_or_method
def user_function(a, b):
return a**b
ufunc = np.frompyfunc(user_function, 2, 1)
ufunc(np.arange(10), np.arange(10))
array([1, 1, 4, 27, 256, 3125, 46656, 823543, 16777216, 387420489], dtype=object)
These functions provide a way to create ufunc-like functions, but they are very slow because they require a Python function call to compute each element, which is a lot slower than NumPy’s C-based ufunc loops.
You may have noticed up until now that ndarray is a homogeneous data container; that is, it represents a block of memory in which each element takes up the same number of bytes, determined by the dtype. On the surface, this would appear to not allow you to represent heterogeneous or tabular-like data. A structured array is an ndarray in which each element can be thought of as representing a struct in C (hence the “struc- tured” name) or a row in a SQL table with multiple named fields:
dtype = [('x', np.float),('y',np.float128)]
sarr = np.array([(1.5, 6),(np.pi, -2)],dtype=dtype)
sarr
array([(1.5, 6.0), (3.141592653589793, -2.0)],
dtype=[('x', '
sarr.dtype.names
('x', 'y')
np.dtype.names
arr.sort() is a in-place function which means it will change the sequence of the original array
- if you sort the view of an array ,the original array will be sorted too
- numpy.sort will create a new array
- arr[::-1] can return a descending array since the sort method will always return the ascending array
arr = np.array([0, 1, 2, 3, 5])
arr.argsort()
array([0, 1, 2, 3, 4])
first_name = np.array(['Bob', 'Jane', 'Steve', 'Bill', 'Barbara'])
last_name = np.array(['Jones', 'Arnold', 'Arnold', 'Jones', 'Walters'])
np.lexsort((first_name, last_name))
array([1, 2, 3, 0, 4])
sort = np.lexsort((first_name, last_name))
zip(last_name[sort], first_name[sort])
[('Arnold', 'Jane'),
('Arnold', 'Steve'),
('Jones', 'Bill'),
('Jones', 'Bob'),
('Walters', 'Barbara')]
> lexisort can sort a hierachical data structure by this
arr.lexisort((secondary order list, primary order list))