numpy的高级操作

参考教程

系列视频:https://www.bilibili.com/video/av11263377

继续继承前文,本文讲介绍numpy使用中一些更高级的知识和操作,这里的高级只是相对前面的基础而言的并不是严格意义上的高级。本文主要所包括的内容有:

  1. numpy中更高级的数组
  2. 讲python的函数转为numpy的Universal funtion
  3. 使用outer函数生成二维数组

Structured Array and Record Array

1. Structured Array

对我自己的工作来说,大多数情况下还是只是使用numpy基本的多维数组,对于structured array就接触的非常的少了。structured array是个很灵活的结构,它很类似C语言中的结构体,能够实现自定的数组类型、其中能包含多种基本数值类型,structured array有如下特点:

  • numpy基本的多维数组只能使用一种类型,而structured array则可以让不同类型的结构混合起来定义
  • 相比纯python的更灵活的结构如list和dict,structured array经过numpy底层的优化让其计算相比前者要高效的多
  • 一行赋值时需要用tuple而不是list
  • 基本类型的所占字节数时固定的,在包含字符串元素时需要注意,字符长度超过定义的长度将会截断舍弃

如下为定义structured array:

1
2
3
4
import numpy as np

user_type = [('name', 'S6'), ('height', 'f8'), ('weight', 'f8'), ('age', 'i8')]
user_type

对其进行初始化和赋值:

1
2
3
4
stru_arr = np.zeros(4, dtype=user_type)
stru_arr[0] = ('kaka', 12, 82.5, 12)
stru_arr[1][0] = 'harry456'
stru_arr[2][0] = 'jack'

中structured array中,由于定义的时候,每一列元素类型都有名称,所以可以使用名称来引索整列:

1
stru_arr['name']

2. record array

record array与structured array类似,不过它特点是在引索某一列时将中括号变成成员引用号,如下将上面的structured array转化为record array,使用“.”访问:

1
2
3
4
5
rec_arr = np.rec.array(stru_arr)
rec_arr[0].name = 'lr'
# 下面两个结果是不一样的
stru_arr[0]['name']
rec_arr[0].name

将普通函数转化为numpy的Universal funtion

NumPy提供了两种基本的对象:ndarray(N-dimensional array object)和 ufunc(universal function object)。ndarray是存储单一数据类型的多维数组,而ufunc则是能够对数组进行处理的函数。ufunc的特点是它能够遍历numpy数组的中的每一个元素,并对其做相同的操作运算,而不需要使用for循环。Numpy内置的许多ufunc函数都是C语言实现的,计算速度非常快。

下面主要演示怎么将普通的python函数变为ufunc,不过这样转化的ufunc只是写法会方便很多,效率提高就不是很多,我自己测试就大概快1倍左右。

1
2
3
4
5
6
def normal_func(x):
return x**2-(x-1)**2

test_dat = np.arange(12).reshape((2,6))
my_ufunc = np.frompyfunc(normal_func, 1, 1)
my_ufunc(test_dat)

上面代码,可以看到使用frompyfunc函数,将普通的python函数转变为了nfunc,其中第一个参数是需要转化的函数名,第二个参数是转化函数的参数个数,第三个参数是返回值个数。

使用outer函数生成二维数组

1. numpy.outer

outer可以用两个向量,生成一个二维数组,直接使用outer函数得到的矩阵原始为向量各个元素的对应乘积,类似于混淆矩阵。如下为用outer函数生成一个记录9x9的乘法表矩阵:

1
2
3
v1 = np.arange(9)+1
v2 = np.arange(9)+1
np.outer(v1, v2)

2. numpy.ufunc.outer

处理直接使用outer外,还支持numpy的ufunc,在这种使用中outer函数的生成方法由ufunc决定。如下就是将操作从默认的乘法换成加法:

1
np.add.outer(v1,v2)
Compartir