Numpy 在数组上应用函数
在数据科学领域中,numpy是一个强大的工具。它不仅提供了快速数组处理和数据分析的工具,还提供了在这些数组上操作的方法。这篇文章将介绍numpy中的另一个强大功能:在一个numpy数组上应用函数。
阅读更多:Numpy 教程
函数应用(apply)的基本概念
对于一个数组中的每一个元素,应用一些函数并产生一个输出值可能是一个很普遍的需求。在numpy中,有两个函数可以实现这个需求:apply_along_axis
和 apply_over_axes
。两者基本上是以不同的方式来实现相同的事情,我们接下来将会详细讨论它们。
在使用apply_along_axis
时,你需要指定要应用的函数和该函数要作用在哪个轴上。例如,在一个包含多个三角函数的数组中,如果你想检查每个三角函数诱导的函数值是否小于0,则可以使用以下代码:
import numpy as np
def check_trig_funcs(x):
out = np.zeros_like(x)
out[x<0] = 1
return out
arr = np.random.uniform(-np.pi, np.pi, size=(3, 4))
res = np.apply_along_axis(check_trig_funcs, 0, np.array([np.sin, np.cos, np.tan]))
print(res)
上述代码的输出应该是一个3×4的数组,它代表着这三个三角函数在输入数组的每个元素处的符号情况(负数为1,否则为0)。
另一方面,如果你想在该数组的所有轴上应用该函数,可以使用apply_over_axes
。例如,下面的代码使用apply_over_axes
来计算一个二维数组的平均沿着每个轴。
def avg(x, axis):
return np.sum(x, axis=axis)/x.shape[axis]
arr = np.random.random(size=(3, 4))
res = np.apply_over_axes(avg, arr, [0, 1])
print(res)
在上述代码中,avg
函数被自动应用到arr的两个轴上,产生了数组的平均值。
apply_along_axis和apply_over_axes使用详解
让我们在这两个函数上做更详细的解释。还是从apply_along_axis
开始。
在之前的例子中,我们使用了函数check_trig_funcs
。该函数需要一个numpy数组作为其输入,并在该数组的每个元素上将该值的符号设置为输出数组中的对应元素。返回的输出数组与输入数组的维度和大小相同。这是一个例子,其中我们使用apply_along_axis
将check_trig_funcs
应用于np.sin,np.cos,np.tan:
def check_trig_funcs(x):
out = np.zeros_like(x)
out[x<0] = 1
return out
print(np.apply_along_axis(check_trig_funcs, 0, np.array([np.sin, np.cos, np.tan])))
输出应该是一个(3, 4)大小的数组,表示三个三角函数在输入数组的每个元素处的符号情况。
现在让我们使用apply_along_axis
来实现以下功能。假设我们有一个多维数组,其中每个轴上都有一些数据。我们希望在每一个向量上应用一个函数,并返回一个标量结果。在这样一个多维数组上,该函数的返回结果将是一个一维数组。下面的代码使用apply_along_axis
计算二维数组arr
的列和,
arr = np.array([[1, 2, 3, 4],[5,6,7,8]])
print(np.apply_along_axis(np.sum, 0, arr))
上述代码输出一个长度为4的数组,其中每个元素都代表输入数组每列的和。
现在让我们来看一下apply_over_axes
函数。该函数能够让我们在数组的所有轴上应用一个函数,同时保留所有维度。例如,让我们计算一个二维数组沿着每一个轴的平均值:
arr = np.array([[1, 2, 3], [4, 5, 6]])
result = np.apply_over_axes(np.mean, arr, [0, 1])
print(result)
输出结果是一个(1, 1)的数组,其中的值为3.5,即原数组的平均值。在这个例子中,mean
函数可以接收任何数组并计算它的平均值。
让我们再看一个更复杂的例子,我们将应用一个带有两个输入参数的自定义函数到一个三维数组上。这个例子是一个计算欧几里得距离的函数,用于计算数组中每对元素的欧几里得距离。在这个例子中,将应用这个函数沿着数组的前两个轴,返回一个大小为(2,2)的数组。
def euclidean_distance(x, y):
return np.sqrt(np.sum((x-y)**2))
arr = np.random.randn(2, 2, 3)
result = np.apply_over_axes(euclidean_distance, arr, axes=[0,1], y=arr[0, 0])
print(result)
在上述代码中,我们使用了apply_over_axes
来计算euclidean_distance
函数在输入数组的前两个轴上的所有元素之间的距离。第三个轴上的元素被视作“特性”或“变量”。最后的输出是一个(2,2)的数组,表示每个点到数组[0,0]的欧几里得距离。
总结
在numpy中,应用函数是一种强大的工具。通过使用apply_along_axis
和apply_over_axes
这两个函数,我们可以在数组的任何轴上应用任何函数,以处理数据或执行任何其他操作。虽然这些函数的使用可能有些棘手,但它们可以节省大量的时间和代码量。