NumPy 是一个运行速度非常快的数学库,主要用于数组计算,支持大量的维度数组与矩阵运算。
简单点说,涉及到数字计算等都可以使用,它的优势在于底层是C语言开发的,处理速度非常快。
看一个例子:计算 a^2 b^2
1.使用列表计算
代码语言:javascript复制import numpy as np
a = [1,2,3,4,5]
b = [6,7,8,9,10]
c = []
for i in range(len(a)):
s = a[i]*a[i] b[i]*b[i]
c.append(s)
print(c)
结果
代码语言:javascript复制[37, 53, 73, 97, 125]
2.使用numpy 计算
代码语言:javascript复制import numpy as np
a = [1,2,3,4,5]
b = [6,7,8,9,10]
c = np.array(a)**2 np.array(b)**2
print(c)
结果
代码语言:javascript复制[ 37 53 73 97 125]
总结:numpy 把列表看成单个元素,省去了从列表中提取出来,然后处理又返回去,直接一步到位。
numpy 在科研计算或者数据分析方面用的还是比较多的,但是一般人平时好像都不怎么用。主要是找不到应用场景或者习惯于用老方法。
其实 numpy 用来造数据或者对多维列表处理是非常方便的,我平常用的主要也是处理这些。
生成全是1的 ndarray 数值
代码语言:javascript复制import numpy as np
# 一维数组:ones生成
one = np.ones(3) # 创建包含3个元素且值全为1的一维数组
print(one)
print(type(one))
结果
代码语言:javascript复制[1. 1. 1.]
<class 'numpy.ndarray'>
数字3写成n,就能生成带有 n 个 1 的数组。
对应的 np.zeros(n) 生成的就是元素值为 0 的数组
生成3行2列,全是1的 ndarray 数值
代码语言:javascript复制import numpy as np
# 二维数组:ones生成
one = np.ones([3,2]) # 创建二维数组
print(one)
print(type(one))
结果
代码语言:javascript复制[[1. 1.]
[1. 1.]
[1. 1.]]
<class 'numpy.ndarray'>
数字3和2表示行数和列数。更多维度继续增加即可,通常2维用的比较多。
生成三维数组,数字可以指定
代码语言:javascript复制import numpy as np
# 三维数组
full = np.full([2,3,4],8)
print(full)
print(type(full))
结果
代码语言:javascript复制[[[8 8 8 8]
[8 8 8 8]
[8 8 8 8]]
[[8 8 8 8]
[8 8 8 8]
[8 8 8 8]]]
<class 'numpy.ndarray'>
生成有序数组
和random库的 range方法一样用,其实包含了random库的全部功能
代码语言:javascript复制import numpy as np
arange = np.arange(1,10,2)
print(arange)
print(type(arange))
结果
代码语言:javascript复制[1 3 5 7 9]
<class 'numpy.ndarray'>
上面的一些方法,对于生成大量的数字非常有用,不用循环就可以搞定。
不过生成的数组类型是 ndarray ,直接和 python 的列表是不能计算操作的,如果习惯使用列表对数据处理,可以使用 tolist() 方法将 ndarray 类型转换成你熟悉的列表数据类型。
代码语言:javascript复制import numpy as np
arange = np.arange(1,10,2)
print(arange)
print(type(arange))
# 转换成列表
new_arange = arange.tolist()
print(new_arange)
print(type(new_arange))
结果
代码语言:javascript复制[1 3 5 7 9]
<class 'numpy.ndarray'>
[1, 3, 5, 7, 9]
<class 'list'>
更多其它方法,可以查看 numpy 的官方文档。
下面看看我是怎样利用numpy 对图片的数据进行处理的。
为了便于观看数据,下面故意图片变小了一些
将上面的图片变成3*3大小的
代码语言:javascript复制img = Image.open("数字_0.jpg").resize((3,3))
它对应的像素数据是下面这样的,3*3*3
代码语言:javascript复制[
[[0, 0, 0], [1, 1, 1], [0, 0, 0]],
[[1, 1, 1], [255, 255, 255], [0, 0, 0]],
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
]
同样的方法,再打开数字 1,获取其对应的数据
代码语言:javascript复制img2 = Image.open("数字_1.jpg").resize((3,3))
它对应的像素数据是下面这样的,3*3*3
代码语言:javascript复制[
[[255, 255, 255], [2, 2, 2], [255, 255, 255]],
[[255, 255, 255], [2, 2, 2], [255, 255, 255]],
[[255, 255, 255], [2, 2, 2], [255, 255, 255]]
]
如果要将两张图片水平方向合成在一起。
只需要将它们的数据,横向组成在一起就可以了。
得到下面这种数据结构。
代码语言:javascript复制[
[[0, 0, 0], [1, 1, 1], [0, 0, 0]],[[255, 255, 255], [2, 2, 2], [255, 255, 255]],
[[1, 1, 1], [255, 255, 255], [0, 0, 0]],[[255, 255, 255], [2, 2, 2], [255, 255, 255]],
[[0, 0, 0], [0, 0, 0], [0, 0, 0]][[255, 255, 255], [2, 2, 2], [255, 255, 255]]
]
用列表的话,相信你应该知道怎么操作,循环遍历拼接就可以了。不过想想还是挺麻烦的。
用 numpy 处理的话就非常简单了。hstack可以将两个列表直接水平方向拼接在一起。
代码语言:javascript复制np.hstack((图片0数据, 图片1数据))
先看一个纯数字列表案例
代码语言:javascript复制import numpy as np
zero = [
(0, 0, 0),
(0, 0, 0),
(0, 0, 0),
]
one = [
(1, 1, 1),
(1, 1, 1),
(1, 1, 1),
]
# Horizontal 水平拼接
a = np.hstack((zero, one))
print(a)
# vertical 竖直拼接
b = np.vstack((zero, one))
print(b)
结果
代码语言:javascript复制[[0 0 0 1 1 1]
[0 0 0 1 1 1]
[0 0 0 1 1 1]]
[[0 0 0]
[0 0 0]
[0 0 0]
[1 1 1]
[1 1 1]
[1 1 1]]
证明确实可以,下面将其用到图片上
代码语言:javascript复制import numpy as np
from PIL import Image
# 打开图片,并将图片数据转换成ndarray 数组
img = np.array(Image.open("数字图片/数字_0.jpg"))
img2 = np.array(Image.open("数字图片/数字_1.jpg"))
# 利用np.hstack将 img 和 img2 数据进行拼接
b = np.hstack((img, img2))
# 将ndarray数据重新转换回图片数据格式
image = Image.fromarray(b)
# 显示图片
image.show()
# 保存图片
image.save("new.jpg")
(全文完)
欢迎转载,转载请注明出处! 欢迎关注公众微信号:叶子陪你玩编程