Numpy Python 使用感想
为了解决学习中遇到的一个小问题,最近使用 Numpy 写了一个小软件。这大概是我写的第一个多少有一点点实用价值的软件了。将 Numpy 使用过程中的一点小收获记录在这里,算作一次小小的总结吧。
Numpy 简介
如果有 MATLAB 的使用经验,那 Numpy 使用起来应该也会比较轻松。
ndarray
Numpy 的基础数据形式是 ndarray,类似于 MATLAB 的矩阵。ndarray 可以是任意维度,numpy.asarray() 函数可以方便的从列表之列的数据结构创建 ndarray。当然,还有很多生成特定矩阵的函数。
有一些我认为至关重要的函数:
# ndarray. 代表一个 ndarray 对象的成员函数,下同
ndarray.dtype
# 得到数组中的数据类型。这不是一个成员函数,不需要函数调用运算符。
ndarray.astype("int")
# 类型转换。注意,该成员函数不改变 ndarray 本身,而是返回改变之后的对象
ndarray.shape
# 得到数组的形状,比如 3*4 的矩阵返回 (3,4)
与 MATLAB 相似,Numpy 中的函数大部分可以直接作用在 ndarray 上。
数据类型
dtype 常用的数据类型有:int,float,bool 等。还可以用严谨的语法指定更加精确的数据类型,但是在我的低性能运算中没必要。
unsigned 数据类型一不小心就会 1-2 得到一个很大的数。测试表明,只要运算对象中有一个 int, 运算结果就不会因为得到负数而溢出。只要运算对象中有一个 float, 运算结果就是 float.
常用函数
本来以为 Numpy 需要好好学一下,实际上发现这就是一个库而已,随用随查就行了。这里是一些常用的函数,实际上在一项工作中可能只会用到一部分。这里只非常简略的记录了一些便于自己查阅的摘要,要了解函数的具体用法和功能,建议使用 IPython 查询在线帮助。
这些函数是在阅读《NumPy Beginner Guide 2nd Edition》时做得笔记。现在想想,在写我的程序时确实已经足够了——实际上大部分都用不到。
dtype
a = arange([
arange(2),
arange(2)
])
a.dtype
a.dtype.itemsize
a.shape
a[0,1]
arange(7,dtype='f')
% 'f' = float; 'i' = int; 'd' = double; 'S' = string; 'u' = uint; 'U'=unicode ...
% 'f8' = float64;
t = dtype([('name', str_, 40), ('numitems', int32), ('price', float32)])
itemz = array([('Meaning of life DVD', 42, 3.14), ('Butter', 13, 2.72)], dtype=t)
slicing and indexing
b=arange(24).reshape(2,3,4)
b[0,0,0]
b[ : ,0,0]
b[0] = b[0 , : , : ] == b[0, ... ]
b[0,1, ::2 ]
b[ ... ,1]
b.where()
b.choose()
shape
b.ravel()
b.flatten()
b=b.reshape()
b.resize()
stacking arrays
hstack((a,b)) == concatenate((a,b),axis=1)
vstack((a,b)) == concatenate((a,b),axis=2)
dstack((a,b)) %if a,b are 2darray, the result is 3darray.
calumn_stack()
row_stack()
spliting
hsplit
vsplit
dsplit
split
Array attributes
ndim
size
itemsize
nbytes = size*itemsize
T % !!!
real
imag
flat % !!! flatiter setable
convert arrays
tolist()
astype()
file I/O
np.savetxt("eye.txt",theArray)
c,v = np.loadtxt('data.csv',delimiter=',',usecols=(6,7),unpack=True)
average, max, min
vwap=np.average(c,weigths=v)
cmean=np.mean(c)
np.max()
np.min()
np.ptp() == np.max()-np.min()
simple statistics
np.msort(c) == np.sort(c,axis=0)
np.median(c) == np.msort(c)[(c.size-1)/2]
np.var(c) == np.mean( (c-c.mean())**2 )
np.diff( arr ).size == arr.size - 1
np.diff(arr)[i] = arr[i] - arr[i+1]
np.where(c,x,y) = [xv if c else yv for (c,xv,yv) in zip(condithon,x,y) ]
np.ptp() #peak to peak
np.std()
Super index
np.where()
np.choose()
np.take()
Make ndarray
np.zeros()
np.eye()
np.identity()
Linear algebra basics
np.linalg
平台,安装
做科学计算,Python3 确实还不太靠谱,主要是某些包支持不良,建议继续使用 Python2。(现在是2015.08)
pip 包管理在安装 Numpy 这种包时不怎么灵光,建议使用打包好的科学计算发行版。这一次我是用的 anaconda.
编程之禅(–>颈椎病康复指南)
- 还是别等学好了工具在着手干活了。我只是需要一个好用的多维数组而已,学习那么多函数一点用处都没有。Numpy 中对我最有用的是其多维数组便利的检索方式,以及 astype 类型转换和数组之间的直接运算 ( 使用 * 等运算符) ,而非线性代数的矩阵运算。用于其他的用途的话,常用功能大概有所不同。
- 性能出现问题的时候,首先改进算法,实在不行了再打工具的主意。Python 有方便的性能分析工具,比如 line_profiler 和 memory_profiler. 然而,不幸的是这工具跟 Win10,IPython 凑在一起的时候好像不太完美,不能在 IPython 中使用魔法指令测试。但在 CMD 上凑合着能用。
本来是看中了 anaconda 的 numba 工具才去用的。这个工具据说能 JIT 编译 Python 的一些使用 Numpy 的函数。然而等我真的遇到性能瓶颈去用的时候,干净利落的出 Bug 了。 - 编程之禅:在最理想的情况下,代码会忠诚的反应我的思想,这就意味着——如果我自己没有把问题完全想明白就动手写代码,肯定写不出什么好东西。确保积极思考而不是用细节麻痹自己。
- 单元测试:至少做到写一个函数测试一个函数,否则出了 Bug 都不知道出在哪里。也可以一边写程序一边写简单地测试脚本。
Python 作为脚本语言在调试方面非常有优势。 - Python 的有些软件包质量很好,比如 Numpy,照着在线帮助系统就能用。有些软件包的在线帮助系统几乎没用,比如 PIL。后者似乎已经几乎停止维护了。PIL这种过旧的包或者 numba 这种过新的包还是避免使用吧。