相关参考:NumPy 教程html
如下取自于:[Python] 01 - Number and Matrix算法
初始化api
mat = np.array([0, 0.5, 1.0, 1.5, 2.0]) mat = np.random.standard_normal((10, 10)) mat = np.zeros((2, 3, 4), dtype='i', order='C')
...
自定义混合类型初始化
统计量数组
[Pandas] 01 - A guy based on NumPyapp
Basic Vectorization 向量化dom
当存在nan元素时,失效;须要排除nan再统计。函数
矩阵取整
取左地板值
仅保留整数位
四舍五入oop
矩阵大小post
import sys sys.getsizeof(a)
矩阵下标
index 表示范围
下标表示范围内的“间隔”
矩阵遍历ui
for x in np.nditer(a, order='F'): Fortran order,便是列序优先; for x in np.nditer(a.T, order='C'): C order,便是行序优先;
扁平化
彻底扁平 ravel
自定义扁平 reshape, resize
转置
堆叠
总体对接 vstack, hstack
各取出一个配对 column_stack, row_stack
元素自增长一维度
拆分
引用,非拷贝
映射关系 view
深拷贝
正态分布
其余分布
丢失的数据类型主要有 None 和 np.nan
(1)np.nan是一个float类型的数据;
(2)None是一个NoneType类型。
(a) 在ndarray中显示时 np.nan会显示nan,若是进行计算 结果会显示为NAN
None显示为None 而且对象为object类型,若是进行计算 结果会报错。
因此ndarray中没法对有缺失值的数据进行计算。
(b) 在Serise中显示的时候都会显示为NAN,都可以视做np.nan
进行计算时能够经过np.sum()获得结果,此时NAN默认为0.0
s1 + 10 对于空值获得的结果为NAN,
若是使用加法 能够经过s1.add(参数,fill_value = 0)指定空值的默认值为0
ndarray.view() 理解为:共享了“同一片物理地址”,但描述部分,例如维度等是单独的。
ndarray.copy() 理解为:深拷贝。
视图通常发生在:
副本通常发生在:
队友:random随机数采样空间。
import numpy as np a = np.linspace(10, 20, 5, endpoint = False) print(a) # 默认底数是 10 a = np.logspace(1.0, 2.0, num = 10) print (a)
NumPy 中包含了一个矩阵库 numpy.matlib,该模块中的函数返回的是一个矩阵,而不是 ndarray 对象。
Ref: numpy教程:矩阵matrix及其运算
NumPy函数库中的matrix与MATLAB中matrices等价。
NumPy 提供了线性代数函数库 linalg,该库包含了线性代数所需的全部功能,能够看看下面的说明:
函数 | 描述 |
---|---|
dot |
两个数组的点积,即元素对应相乘。(就是 “矩阵相乘”) |
vdot |
两个向量的点积 |
inner |
两个数组的内积(向量积) |
matmul |
两个数组的矩阵积 |
determinant |
数组的行列式 |
solve |
求解线性矩阵方程 |
inv |
计算矩阵的乘法逆矩阵 |
点积和内积的区别:difference between numpy dot() and inner()
In [103]: a=np.array([[1,2],[3,4]]) In [104]: b=np.array([[11,12],[13,14]]) In [105]: np.dot(a,b) # 矩阵乘法: 1*11+2*13 = 37 Out[105]: array([[37, 40], [85, 92]]) In [106]: np.inner(a,b) # 1*11+2*12 = 35, 1*13+2*14 = 41 Out[106]: array([[35, 41], [81, 95]])
进一步考察inner:Ordinary inner product of vectors for 1-D arrays (without complex conjugation), in higher dimensions a sum product over the last axes.
In [118]: a=np.array([[1,2],[3,4],[5,6]]) In [119]: b=np.array([[7,8],[9,10],[11,12]]) In [120]: a Out[120]: array([[1, 2], [3, 4], [5, 6]]) In [121]: b Out[121]: array([[ 7, 8], [ 9, 10], [11, 12]]) In [122]: np.inner(a,b) Out[122]: array([[ 23, 29, 35], [ 53, 67, 81], [ 83, 105, 127]])
相似于filter。
import numpy as np x = np.array([[ 0, 1, 2],[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]]) print ('咱们的数组是:') print (x) print ('\n')
# 如今咱们会打印出大于 5 的元素 print ('大于 5 的元素是:') print (x[x > 5])
# 元素位置被"True/False"置换
print (x > 5)
Output:
咱们的数组是: [[ 0 1 2] [ 3 4 5] [ 6 7 8] [ 9 10 11]] 大于 5 的元素是: [ 6 7 8 9 10 11] array([[False, False, False], [False, False, False], [ True, True, True], [ True, True, True]])
(a) 传入顺序索引数组
import numpy as np print (x[[4,2,1,7]])
(b) 传入多个索引数组(二级操做,先fiter一次,再filter一次)
import numpy as np x=np.arange(32).reshape((8,4)) print (x[np.ix_([1,5,7,2],[0,3,1,2])])
有点至关于x[[1,5,7,2]][[0,3,1,2]],但不具备顺序性。
In [193]: array_3 Out[193]: array([nan, 0., 1., 2., nan]) In [194]: ix = ~np.isnan(array_3) In [195]: array_3[ix] Out[195]: array([0., 1., 2.]) In [196]: array_3[ix].mean() Out[196]: 1.0
##########################################
# 做为对比,下面的这个由于nan而没法统计
##########################################
In [197]: array_3.mean() Out[197]: nan
通常不要用这种“隐式转换”。
import numpy as np a = np.array([[ 0, 0, 0], [10,10,10], [20,20,20], [30,30,30]]) b = np.array([1,2,3]) print(a + b)
import numpy as np a = np.arange(0,60,5) a = a.reshape(3,4) print ('第一个数组为:') print (a)
print ('\n') print ('第二个数组为:') b = np.array([1, 2, 3, 4], dtype = int) print (b)
print ('\n') print ('修改后的数组为:') for x,y in np.nditer([a,b]): print ("%d:%d" % (x,y), end=", " )
Output:
第一个数组为: [[ 0 5 10 15] [20 25 30 35] [40 45 50 55]] 第二个数组为: [1 2 3 4] 修改后的数组为: 0:1, 5:2, 10:3, 15:4, 20:1, 25:2, 30:3, 35:4, 40:1, 45:2, 50:3, 55:4,
默认迭代器选择以更有效的方式对数组进行迭代;固然也能够强制“风格顺序”。
import numpy as np a = np.arange(0,60,5) a = a.reshape(3,4) print ('原始数组是:') print (a)
print ('\n') print ('以 C 风格顺序排序:') for x in np.nditer(a, order = 'C'): print (x, end=", " )
print ('\n') print ('以 F 风格顺序排序:') for x in np.nditer(a, order = 'F'): print (x, end=", " )
结果:
原始数组是: [[ 0 5 10 15] [20 25 30 35] [40 45 50 55]] 以 C 风格顺序排序: 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 以 F 风格顺序排序: 0, 20, 40, 5, 25, 45, 10, 30, 50, 15, 35, 55,
nditer 对象有另外一个可选参数 op_flags。 默认状况下,nditer 将视待迭代遍历的数组为只读对象(read-only)。
为了在遍历数组的同时,实现对数组元素值得修改,必须指定 read-write 或者 write-only 的模式。
import numpy as np a = np.arange(0,60,5) a = a.reshape(3,4) print ('原始数组是:') print (a)
print ('\n') for x in np.nditer(a, op_flags=['readwrite']): x[...]=2*x print ('修改后的数组是:') print (a)
若是想获得“列的分组”结果,考虑以下方法。
或者考虑ndarrary.flatten(order='F')。
import numpy as np
a = np.arange(0,60,5) a = a.reshape(3,4)
print ('原始数组是:') print (a) print ('\n') print ('修改后的数组是:')
for x in np.nditer(a, flags = ['external_loop'], order = 'C'): print (x, end=", " ) print() for x in np.nditer(a, flags = ['external_loop'], order = 'F'): print (x, end=", " )
Output:
原始数组是: [[ 0 5 10 15] [20 25 30 35] [40 45 50 55]] 修改后的数组是: [ 0 5 10 15 20 25 30 35 40 45 50 55], [ 0 20 40], [ 5 25 45], [10 30 50], [15 35 55],
numpy中的ravel()、flatten()、squeeze()都有将多维数组转换为一维数组的功能,区别:
ravel() | 若是没有必要,不会产生源数据的副本。 |
flatten() | 返回源数据的副本。 |
squeeze() | 只能对维数为1的维度降维。 |
如下函数用于对 dtype 为 numpy.string_ 或 numpy.unicode_ 的数组执行向量化字符串操做。 它们基于 Python 内置库中的标准字符串函数。
这些函数在字符数组类(numpy.char)中定义。
函数 | 描述 |
---|---|
add() |
对两个数组的逐个字符串元素进行链接 |
multiply() | 返回按元素多重链接后的字符串 |
center() |
居中字符串 |
capitalize() |
将字符串第一个字母转换为大写 |
title() |
将字符串的每一个单词的第一个字母转换为大写 |
lower() |
数组元素转换为小写 |
upper() |
数组元素转换为大写 |
split() |
指定分隔符对字符串进行分割,并返回数组列表 |
splitlines() |
返回元素中的行列表,以换行符分割 |
strip() |
移除元素开头或者结尾处的特定字符 |
join() |
经过指定分隔符来链接数组中的元素 |
replace() |
使用新字符串替换字符串中的全部子字符串 |
decode() |
数组元素依次调用str.decode |
encode() |
数组元素依次调用str.encode |
byteswap() |
将 ndarray 中每一个元素中的字节进行大小端转换 |
数组维度操做。
import numpy as np x = np.array([[[0,1],[2,3]],[[4,5],[6,7]]]) y = np.swapaxes(x,0,2) print(y)
Output: x轴(0) 和 z轴(2) 调换的结果
[[[0 4] [2 6]] [[1 5] [3 7]]]
一个要点:新添加的轴,必然是shape = 1的。
import numpy as np x = np.array(([1,2],[3,4])) print ('数组 x:') print (x) print ('\n') y = np.expand_dims(x, axis = 0) print ('数组 y:') print (y) print ('\n') print ('数组 x 和 y 的形状:') print (x.shape, y.shape) print ('\n') # 在位置 1 插入轴 y = np.expand_dims(x, axis = 1) print ('在位置 1 插入轴以后的数组 y:') print (y) print ('\n') print ('x.ndim 和 y.ndim:') print (x.ndim,y.ndim) print ('\n') print ('x.shape 和 y.shape:') print (x.shape, y.shape)
输出结果为:
数组 x: [[1 2] [3 4]] 数组 y: [[[1 2] [3 4]]] 数组 x 和 y 的形状: (2, 2) (1, 2, 2) 在位置 1 插入轴以后的数组 y: [[[1 2]] [[3 4]]] x.ndim 和 y.ndim: 2 3 x.shape 和 y.shape: (2, 2) (2, 1, 2)
x的维度变高后,y的维度经过 “broadcast” 自动升维。
import numpy as np x = np.array([[1], [2], [3]]) y = np.array([4, 5, 6]) # 对 y 广播 x b = np.broadcast(x,y) # 它拥有 iterator 属性,基于自身组件的迭代器元组 print ('对 y 广播 x:') r,c = b.iters # Python3.x 为 next(context) ,Python2.x 为 context.next() print (next(r), next(c)) print (next(r), next(c)) print (next(r), next(c)) print (next(r), next(c)) print ('\n')
Output:
对 y 广播 x: 1 4 1 5 1 6 2 4
import itertools class cartesian(object): def __init__(self): self._data_list=[] def add_data(self,data=[]): #添加生成笛卡尔积的数据列表 self._data_list.append(data) def build(self): #计算笛卡尔积 for item in itertools.product(*self._data_list): print(item) if __name__=="__main__": car = cartesian() car.add_data([1,2,3]) car.add_data([4,5,6]) car.build()
print ('广播对象的形状:') print (b.shape) print ('\n')
b = np.broadcast(x,y) c = np.empty(b.shape) print ('手动使用 broadcast 将 x 与 y 相加:') print (c.shape) print ('\n')
# 方案一:手动相加 c.flat = [u + v for (u,v) in b] # <----很是妙!c实际上是假降维 print ('调用 flat 函数:') print (c) print ('\n')
# 方案二:自动相加;得到了和 NumPy 内建的广播支持相同的结果 print ('x 与 y 的和:') print (x + y)
Output:
广播对象的形状: (3, 3) 手动使用 broadcast 将 x 与 y 相加: (3, 3) 调用 flat 函数: [[5. 6. 7.] [6. 7. 8.] [7. 8. 9.]] x 与 y 的和: [[5 6 7] [6 7 8] [7 8 9]]
将数组广播到新形状,有点“复制”的意思;但倒是只读,难道是“伪复制”?是的,内存没有增长。
可使用 sys.getsizeof(<variable>) 获取变量大小。
import numpy as np a = np.arange(4).reshape(1,4) print ('原数组:') print (a) print ('\n') print ('调用 broadcast_to 函数以后:') print (np.broadcast_to(a,(4,4)))
Output:
原数组: [[0 1 2 3]] 调用 broadcast_to 函数以后: [[0 1 2 3] [0 1 2 3] [0 1 2 3] [0 1 2 3]]
按照某个字段排序。
import numpy as np a = np.array([[3,7],[9,1]]) print ('咱们的数组是:') print (a) print ('\n')
print ('调用 sort() 函数:') print (np.sort(a)) print ('\n')
print ('按列排序:') print (np.sort(a, axis = 0)) print ('\n')
# 在 sort 函数中排序字段 dt = np.dtype([('name', 'S10'),('age', int)]) a = np.array([("raju",21),("anil",25),("ravi", 17), ("amar",27)], dtype = dt)
print ('咱们的数组是:') print (a) print ('\n')
print ('按 name 排序:') print (np.sort(a, order = 'name'))
返回索引,但可经过x[y]的形式巧妙地获得结果。
import numpy as np x = np.array([3, 1, 2]) print ('咱们的数组是:') print (x) print ('\n')
print ('对 x 调用 argsort() 函数:') y = np.argsort(x) print (y) print ('\n')
print ('以排序后的顺序重构原数组:') print (x[y]) print ('\n')
print ('使用循环重构原数组:') for i in y: print (x[i], end=" ")
每一列表明一个序列,排序时优先照顾靠后的列。
注意,这里一列数据传入的是tuple。
import numpy as np nm = ('raju','anil','ravi','amar') dv = ('f.y.', 's.y.', 's.y.', 'f.y.') ind = np.lexsort((dv, nm)) print ('调用 lexsort() 函数:') print (ind) print ('\n') print ('使用这个索引来获取排序后的数据:') print ([nm[i] + ", " + dv[i] for i in ind])
msort(a) | 数组按第一个轴排序,返回排序后的数组副本。np.msort(a) 相等于 np.sort(a, axis=0)。 |
sort_complex(a) | 对复数按照先实部后虚部的顺序进行排序。 |
(1) 排序数组索引为 3 的数字,比该数字小的排在该数字前面,比该数字大的排在该数字的后面。
>>> a = np.array([3, 4, 2, 1]) >>> np.partition(a, 3) # 将数组 a 中全部元素(包括重复元素)从小到大排列,3 表示的是排序数组索引为 3 的数字,比该数字小的排在该数字前面,比该数字大的排在该数字的后面 array([2, 1, 3, 4]) >>> >>> np.partition(a, (1, 3)) # 小于 1 的在前面,大于 3 的在后面,1和3之间的在中间 array([1, 2, 3, 4])
(2) 第 3 小(index=2)的值
>>> arr = np.array([46, 57, 23, 39, 1, 10, 0, 120]) >>> arr[np.argpartition(arr, 2)[2]] 10
(3) 第 2 大(index=-2)的值
>>> arr[np.argpartition(arr, -2)[-2]] 57
(4) 同时找到第 3 和第 4 小的值。
>>> arr[np.argpartition(arr, [2,3])[2]] 10 >>> arr[np.argpartition(arr, [2,3])[3]] 23
(5) numpy.argmax() 和 numpy.argmin()函数分别沿给定轴返回最大和最小元素的索引。
numpy.nonzero() 函数返回输入数组中非零元素的索引。
numpy.where() 函数返回输入数组中知足给定条件的元素的索引。
End.