dai*_*ain 5 python arrays numpy vectorization numpy-broadcasting
假设我有一个这样的数组:
import numpy as np
base_array = np.array([-13, -9, -11, -3, -3, -4, 2, 2,
2, 5, 7, 7, 8, 7, 12, 11])
Run Code Online (Sandbox Code Playgroud)
假设我想知道:"有多少元素base_array大于4?" 这可以通过利用广播来完成:
np.sum(4 < base_array)
Run Code Online (Sandbox Code Playgroud)
答案是这样的7.现在,假设不是比较单个值,而是想在数组上执行此操作.换句话说,每个值c的comparison_array,发现的许多元素如何base_array都大于c.如果我以天真的方式这样做,它显然会失败,因为它不知道如何正确地广播它:
comparison_array = np.arange(-13, 13)
comparison_result = np.sum(comparison_array < base_array)
Run Code Online (Sandbox Code Playgroud)
输出:
Traceback (most recent call last):
File "<pyshell#87>", line 1, in <module>
np.sum(comparison_array < base_array)
ValueError: operands could not be broadcast together with shapes (26,) (16,)
Run Code Online (Sandbox Code Playgroud)
如果我能以某种方式comparison_array将广播的每个元素都变成base_array形状,那就可以解决这个问题.但我不知道如何做这样的"元素广播".
现在,我知道如何使用列表理解来实现这两种情况:
first = sum([4 < i for i in base_array])
second = [sum([c < i for i in base_array])
for c in comparison_array]
print(first)
print(second)
Run Code Online (Sandbox Code Playgroud)
输出:
7
[15, 15, 14, 14, 13, 13, 13, 13, 13, 12, 10, 10, 10, 10, 10, 7, 7, 7, 6, 6, 3, 2, 2, 2, 1, 0]
Run Code Online (Sandbox Code Playgroud)
但是众所周知,这将比numpy大型阵列上的正确矢量化实现慢几个数量级.那么,我应该如何做到这一点,numpy以便快速?理想情况下,此解决方案应扩展到广播工作的任何类型的操作,而不仅仅是大于或小于此示例.
您可以简单地向比较数组添加一个维度,以便比较沿着新维度在所有值上“延伸”。
>>> np.sum(comparison_array[:, None] < base_array)
228
Run Code Online (Sandbox Code Playgroud)
这是广播的基本原理,适用于各种操作。
如果需要沿轴求和,只需指定比较后要沿其求和的轴即可。
>>> np.sum(comparison_array[:, None] < base_array, axis=1)
array([15, 15, 14, 14, 13, 13, 13, 13, 13, 12, 10, 10, 10, 10, 10, 7, 7,
7, 6, 6, 3, 2, 2, 2, 1, 0])
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
732 次 |
| 最近记录: |