Numpy操作集锦

  |  

摘要: 本文记录一下日常的项目中遇到的 numpy 的问题以及解决方案

【对算法,数学,计算机感兴趣的同学,欢迎关注我哈,阅读更多原创文章】
我的网站:潮汐朝夕的生活实验室
我的公众号:算法题刷刷
我的知乎:潮汐朝夕
我的github:FennelDumplings
我的leetcode:FennelDumplings


参考资料:


扩展维度

X 为 shape 为 (2, 3) 的数组, X = np.random.rand(2, 3),在 axis = 0, 1, 2 上扩展一维。

  • 在 axis=0 加一维,shape 变为 (1, 2, 3)
1
2
X[np.newaxis,:,:]
np.expand_dims(X, axis=0)
  • 在 axis=1 加一维,shape 变为 (2, 1, 3)
1
2
X[,:np.newaxis,:]
np.expand_dims(X, axis=1)
  • 在 axis=2 加一维,shape 变为 (2, 3, 1)
1
2
X[:,:,np.newaxis]
np.expand_dims(X, axis=2)

在一个轴上做同一个操作

  • apply_along_axis(func, axis, arr, *args, **kwargs):

将函数应用于沿给定轴的1-D切片

其中 func 是自定义的一个函数,函数 func(arr) 中的arr是一个数组,函数的主要功能就是对数组里的每一个元素进行变换,得到目标的结果。其中axis表示函数func对数组arr作用的轴。可选参数 *args, **kwargs 都是func()函数额外的参数。

返回的是一个根据 func() 函数以及维度 axis 运算后得到的的数组

例子

随机生成 10 行 2 列的二维矩阵,对每一行的两个数,将大的放后面,小的放前面。

1
2
3
4
5
6
7
def func(x):
if x[0] > x[1]:
x[0], x[1] = x[1], x[0]
return x

X = np.random.rand(10, 2)
Z = np.apply_along_axis(func1d=func, arr=X, axis=1)

如果涉及到对多个轴做相同的操作,可以看 apply_over_axes(func, arr, axes)

在上面的例子中,强行用 apply_over_axes(func, arr, axes) 形成同样效果的代码如下

1
2
3
4
def method(x, axis):
return np.apply_along_axis(func1d=func, arr=x, axis=axis)

Z = np.apply_over_axes(func=method, a=X, axes=[1])

在多维数组的多个轴上做同一个操作

  • apply_over_axes(func, arr, axes)

在多个轴上重复应用功能。

其中 arr 是需要操作的输入数组,func 是操作函数,axes是需要操作的轴的列表。其中 func 的参数为 arr 和 axis。

apply_over_axes 会按 axes 中各轴的顺序调用 func(x, axis),其中 x 是 上一次 func(x, axis) 的结果。这里面的细节比较多,可以参考下面的接口文档。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
def apply_over_axes(func, a, axes):
"""
Apply a function repeatedly over multiple axes.
`func` is called as `res = func(a, axis)`, where `axis` is the first
element of `axes`. The result `res` of the function call must have
either the same dimensions as `a` or one less dimension. If `res`
has one less dimension than `a`, a dimension is inserted before
`axis`. The call to `func` is then repeated for each axis in `axes`,
with `res` as the first argument.
Parameters
----------
func : function
This function must take two arguments, `func(a, axis)`.
a : array_like
Input array.
axes : array_like
Axes over which `func` is applied; the elements must be integers.
Returns
-------
apply_over_axis : ndarray
The output array. The number of dimensions is the same as `a`,
but the shape can be different. This depends on whether `func`
changes the shape of its output with respect to its input.

例子

shape 为 (2, 2, 3) 的数组,按顺序对轴 1, 0 求和。下面的代码中,method 和 method2 两种方法结果一样。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def func(x):
return sum(x)

def method(x, axis):
return np.apply_along_axis(func1d=func, arr=x, axis=axis)

def method2(x, axis):
return np.sum(x, axis)

X = np.array([[[1, 2, 3], [4, 5, 6]]
,[[1, 2, 3], [4, 5, 6]]
])
Z = np.apply_over_axes(func=method, a=X, axes=[1, 0])
Z = np.apply_over_axes(func=method2, a=X, axes=[1, 0])

对每个元素做同一个操作

func = frompyfunc(pyfunc, 1, 1),pyfunc 是要使用的函数,第二个参数为 pyfunc 中的参数个数,第三个参数为 pyfunc 中的返回值的个数。

有一个一维数组 arr,其值为 (0, 1) 上的均匀分布,现在要检查每个元素 arr[i],如果大于 0.5,则将其改为 1 - arr[i]。

1
2
3
4
5
6
7
8
9
def pyfunc(x):
if x > 0.5:
x = 1 - x
return x

func = np.frompyfunc(pyfunc, 1, 1)

X = np.random.uniform(0, 1, 10)
X = func(X)

指定概率随机取值

1
2
p = np.array([0.1, 0.0, 0.7, 0.2])
index = np.random.choice([0, 1, 2, 3], p = p.ravel())

Share