Python快速处理数据的Broadcasting

来源:互联网 发布:m3网络平台搭建 编辑:程序博客网 时间:2024/05/14 03:43

标准安装的Python中用列表(list)保存一组值,可以用来当作数组使用,不过由于列表的元素可以是任何对象,因此列表中所保存的是对象的指针。这样为了保存一个简单的[1,2,3],需要有3个指针和三个整数对象。对于数值运算来说这种结构显然比较浪费内存和CPU计算时间。

此外Python还提供了一个array模块,array对象和列表不同,它直接保存数值,和C语言的一维数组比较类似。但是由于它不支持多维,也没有各种运算函数,因此也不适合做数值运算。

NumPy的诞生弥补了这些不足,NumPy提供了两种基本的对象:ndarray(N-dimensional array object)和 ufunc(universal function object)。ndarray(下文统一称之为数组)是存储单一数据类型的多维数组,而ufunc则是能够对数组进行处理的函数。

存取元素

>>> a = np.arange(10)>>> a[5]    # 用整数作为下标可以获取数组中的某个元素5>>> a[3:5]  # 用范围作为下标获取数组的一个切片,包括a[3]不包括a[5]array([3, 4])>>> a[:5]   # 省略开始下标,表示从a[0]开始array([0, 1, 2, 3, 4])>>> a[:-1]  # 下标可以使用负数,表示从数组后往前数array([0, 1, 2, 3, 4, 5, 6, 7, 8])>>> a[2:4] = 100,101    # 下标还可以用来修改元素的值>>> aarray([  0,   1, 100, 101,   4,   5,   6,   7,   8,   9])>>> a[1:-1:2]   # 范围中的第三个参数表示步长,2表示隔一个元素取一个元素array([  1, 101,   5,   7])>>> a[::-1] # 省略范围的开始下标和结束下标,步长为-1,整个数组头尾颠倒array([  9,   8,   7,   6,   5,   4, 101, 100,   1,   0])>>> a[5:1:-2] # 步长为负数时,开始下标必须大于结束下标array([  5, 101])

注意python里的索引是从0开始的,:4表示的是0,1,2,3行(列),这与matlab不同。

广播Broadcasting

当我们使用ufunc函数对两个数组进行计算时,ufunc函数会对这两个数组的对应元素进行计算,因此它要求这两个数组有相同的大小(shape相同)。如果两个数组的shape不同的话,避免多重循环,会进行如下的广播(broadcasting)处理:

  1. 让所有输入数组都向其中shape最长的数组看齐,shape中不足的部分都通过在前面加1补齐
  2. 输出数组的shape是输入数组shape的各个轴上的最大值
  3. 如果输入数组的某个轴和输出数组的对应轴的长度相同或者其长度为1时,这个数组能够用来计算,否则出错
  4. 当输入数组的某个轴的长度为1时,沿着此轴运算时都用此轴上的第一组值

Broadcasting操作会使程序更简洁与高效。

例子:

import numpy as np# Compute outer product of vectorsv = np.array([1,2,3])  # v has shape (3,)w = np.array([4,5])    # w has shape (2,)# To compute an outer product, we first reshape v to be a column# vector of shape (3, 1); we can then broadcast it against w to yield# an output of shape (3, 2), which is the outer product of v and w:# [[ 4  5]#  [ 8 10]#  [12 15]]print np.reshape(v, (3, 1)) * w# Add a vector to each row of a matrixx = np.array([[1,2,3], [4,5,6]])# x has shape (2, 3) and v has shape (3,) so they broadcast to (2, 3),# giving the following matrix:# [[2 4 6]#  [5 7 9]]print x + v# Add a vector to each column of a matrix# x has shape (2, 3) and w has shape (2,).# If we transpose x then it has shape (3, 2) and can be broadcast# against w to yield a result of shape (3, 2); transposing this result# yields the final result of shape (2, 3) which is the matrix x with# the vector w added to each column. Gives the following matrix:# [[ 5  6  7]#  [ 9 10 11]]print (x.T + w).T# Another solution is to reshape w to be a row vector of shape (2, 1);# we can then broadcast it directly against x to produce the same# output.print x + np.reshape(w, (2, 1))# Multiply a matrix by a constant:# x has shape (2, 3). Numpy treats scalars as arrays of shape ();# these can be broadcast together to shape (2, 3), producing the# following array:# [[ 2  4  6]#  [ 8 10 12]]print x * 2
0 0
原创粉丝点击