Python本身支持的数据结构不多,除了int、float和string等一些常规的之外,还有列表、元祖、字典,都有自己的属性和方法,怎么说呢,功能已经足够强大,解决一般的问题已经足够,可当数据量增大,计算形式变得多样,这种普通的数据结构效率不高,况且python本身对于数组的支持不是很好,这也是为什么会有一批类似于numpy、scipy、panda等第三方库,大大扩展了python的功能,胶水的本质越来越突出。学习的成本也不高,不会像重新学一门语言那么困难,况且据了解,python的科学计算能力已经不亚于R还有Matlab,这两个都没有学过,不敢妄言。
自己对于numpy的学习也是刚起步,算不上很精通,总之,慢慢的学吧。
Example1
Numpy有自己的数据结构,即数组,可以用arange()和array()来创建
# -*- coding:utf-8 -*- # 先导入numpy库 import numpy as np # arange()的用法与range()类似 a = np.arange(1, 10, 2) print ‘a:‘, a # 利用array()可以直接创建 b = np.array([[1, 2], [1, 2]]) print ‘b:‘, b # arange()与array()结合 c = np.array([np.arange(2), np.arange(2)]) print ‘c:‘, c |
结果如下
Example2
选取数组中的元素,同样也是从0开始
d = np.array([[1, 2], [3, 4]]) # 这是一个2*2的数组 print d # 选取第一行第一个元素 print d[0, 0] # 选取第二行第一个元素 print d[1, 0] |
结果如下:
Numpy同样支持切片操作,使用方式与python一致
e = np.arange(10) print e print e[1:5:2] # 5是不包含的 |
结果如下:
Example3
对于多维数组,操作方法类似,但有一些小技巧
(一)生成一个多维数组
# reshape()可以改变数组的维度 f = np.arange(24).reshape(2, 3, 4) print f # 可以通过shape属性查看数据的维度信息 print f.shape |
结果如下:
(二)切片和索引
其实对于一个3*3的数组a,选取的方法总结起来就是a[start:end:step, start:end:step, start:end:step],并且对于多个冒号可以用…代替,这个需要慢慢体会
# 把数组f理解为一个二层的楼,每一层有3行4列个房间 print u‘选取第一层的所有房间‘, f[0] # 等价于f[0, :, :]和f[0, ...] print u‘选取第一层楼第二行的房间‘, f[0, 1] # 等价于f[0, 1, :] # 也可以按照一定的步长 print u‘选取第一层楼第一和第三行‘, f[0, 0:3:2] |
结果如下
Example4
改变数组的维度
# 展平操作,两种方式 g = np.array([np.arange(5), np.arange(5)]) print u"数组g:", g print "ravel:", g.ravel() print "flatten:", g.flatten() # 设置维度,三种方式 print "reshape:", g.reshape(5, 2) print u"数组g:", g # g本身并没有变 # 以下两种方式数组g被改变 g = np.array([np.arange(5), np.arange(5)]) g.shape = (5, 2) print "shape:", g g = np.array([np.arange(5), np.arange(5)]) g.resize((5, 2)) print "resize:", g # 转置 # 数组本身有一个T属性 g = np.array([np.arange(5), np.arange(5)]) print "T:", g.T # 可以用transpose方法 g = np.array([np.arange(5), np.arange(5)]) print "transpose:", g.transpose() |
结果如下:
Example5
数组的组合,有水平组合、垂直组合和深度组合等多种组合方式,很复杂,很独特,但很有用
# 数组的组合 # 先创建两个数组 h = np.arange(9).reshape(3, 3) print u"数组h:", h i = 2 * h print u"数组i:", i # 水平组合hstack print "hstack:", np.hstack((h, i)) # concatenate函数也可以,不过要设置参数 print "concatenate(axis=1):", np.concatenate((h, i), axis=1) # 垂直组合vstack print "vstack:", np.vstack((h, i)) # 当然也可以用concatenate,axis默认为0 print "concatenate(axis=0):", np.concatenate((h, i)) # 深度组合dstack,像是切蛋糕 print "dstack:", np.dstack((h, i)) # 列组合column_stack, 二维数组column_stack与hstack一样 print "column_stack:", np.column_stack((h, i)) # 行组合row_stack, 二维数组row_stack与vstack一样 print "row_stack:", np.row_stack((h, i)) |
结果如下:
Example6
数组的分割,其实就是组合的逆操作
# 数组的分割 j = np.arange(9).reshape(3, 3) print u"数组j:", j # 水平分割hsplit,可以理解为沿着水平方向进行分割 print "hsplit:", np.hsplit(j, 3) # 也可以用split,指定axis=1 print "split(axis=1):", np.split(j, 3, axis=1) # 垂直分割vsplit,可以理解为沿着垂直方向进行分割 print "vsplit:", np.vsplit(j, 3) # 同样的split也可以,axis默认即为0 print "split(axis=0):", np.split(j, 3) # 深度分割dsplit,至少三维 k = np.arange(27).reshape(3, 3, 3) print k print "dsplit:", np.dsplit(k, 3) |
结果如下:
组合就是把多个数组合成一个,分割就是把一个数组分成多个数组
Example7
数组的属性
l = np.arange(20).reshape(2, 10) print u"数组l:", l print u"数组的维数:", l.ndim print u"数组的维度:", l.shape print u"数组元素的个数:", l.size print u"数组单个元素所占内存:", l.itemsize print u"数组所占内存:", l.nbytes print u"转置:", l.T print u"数组元素类型:", l.dtype # flat属性返回一个flatier对象(扁平迭代器) f = l.flat print f # 遍历 for item in f: print item # 直接获取 print "l.flat[2]:", l.flat[2] print "l.flat[[1, 2, 3]]:", l.flat[[1, 2, 3]] # 可赋值 l.flat[[1, 2, 3]] = 1 print u"flat赋值:", l |
结果如下:
数组的属性有很多,经常用,要记牢
Example8
数组的转换
# 数组的转换 # numpy数组转换为list m = np.arange(5) print m.tolist() # astype可以指定数据类型 print m.astype(complex) |
结果如下:
总结:数组这种数据类型几乎可以说是numpy的核心,极大的拓展了Python的科学计算能力,依附在数组这个对象上有很多属性和方法,使用起来很方便,不用自己再一一实现,可以将更多的精力放在解决具体的问题上。以上所写都只是入门的知识,接下来仍有很多要学,可以结合numpy的帮助文档和别人的博客
源代码可以参考这里:https://github.com/Lucifer25/Learn-Python/blob/master/numpy_exercise1.py
参考书籍:Python数据分析基础教程(Numpy学习指南) 人民邮电出版社 。。。。错字挺多,内容还算翔实