为了账号安全,请及时绑定邮箱和手机立即绑定

Numpy for 循环矢量化:使用 np.all 广播和测试唯一元素

Numpy for 循环矢量化:使用 np.all 广播和测试唯一元素

慕哥6287543 2022-12-27 15:46:41
工作循环,预期结果我正在尝试使用非常大的数据集对代码中的慢速 for 循环进行矢量化,以根据测试删除重复项。结果应该只保留前 3 个元素唯一的元素,而第 4 个元素是所有重复项中最大的元素。例如in = np.array(((0, 12, 13, 1), (0, 12, 13, 10), (1, 12, 13, 2)))应该成为out = np.array(((0, 12, 13, 10), (1, 12, 13, 2)))使用 for 循环实现这一点很简单,但正如我提到的,它非常慢。unique = np.unique(in[:, :3], axis=0)out = np.empty((0, 4))for i in unique:    out = np.vstack((out, np.hstack((i[:], np.max(in[np.all(in[:, :3] == i[:], axis=1)][:, 3])))))我试过的 (1)当我尝试通过将每个替换为以下索引来删除带有索引的 for 循环i[:]时unique[np.arange(unique.shape[0])]:out = np.vstack((out, np.hstack((unique[np.arange(unique.shape[0])], np.max(in[np.all(in[:, :3].astype(int) == unique[np.arange(unique.shape[0])], axis=1)][:, 3])))))Numpy 抱怨输入形状连同所有:Traceback (most recent call last):  File "<stdin>", line 1, in <module>  File "<__array_function__ internals>", line 6, in all  File "/usr/local/lib/python3.6/dist-packages/numpy/core/fromnumeric.py", line 2351, in all    return _wrapreduction(a, np.logical_and, 'all', axis, None, out, keepdims=keepdims)  File "/usr/local/lib/python3.6/dist-packages/numpy/core/fromnumeric.py", line 90, in _wrapreduction    return ufunc.reduce(obj, axis, dtype, out, **passkwargs)numpy.AxisError: axis 1 is out of bounds for array of dimension 0我试过的(2)根据输入此问题时 StackOverflow 的建议(Broadcasting/Vectorizing inner and outer for loops in python/NumPy):newout = np.vstack((newout, np.hstack((tempunique[:, None], np.max(inout[np.all(inout[:, :3].astype(int) == tempunique[:, None], axis=1)][:, 3])))))我收到一个错误,抱怨输入和输出之间的大小不匹配:Traceback (most recent call last):  File "<stdin>", line 1, in <module>IndexError: boolean index did not match indexed array along dimension 0; dimension is 3 but corresponding boolean dimension is 2重述问题是否有正确的方法来广播我的索引以消除 for 循环?
查看完整描述

1 回答

?
HUH函数

TA贡献1836条经验 获得超4个赞

我对您的用例了解不够,无法确定是否值得引入 Pandas,但在 Pandas 中有效地这样做只需要几行代码:


import numpy as np

import pandas as pd


in_array = np.array(((0, 12, 13, 1), (0, 12, 13, 10), (1, 12, 13, 2)))

in_df = pd.DataFrame(in_array)



# group by unique combinations of the 0th, 1st, and 2nd columns, then take the

# max of the 3rd column in each group. `reset_index` change cols 0-2 from index

# back to normal columns

out_df = in_df.groupby([0, 1, 2])[3].max().reset_index()

out_array = out_df.values


print(out_array)

# Output:

# [[ 0 12 13 10]

#  [ 1 12 13  2]]

一个简单的计时测试表明,使用 Pandas 处理一个 100000 行随机生成的输入数组需要 0.0117 秒,而使用 for 循环实现需要 2.6103 秒。


查看完整回答
反对 回复 2022-12-27
  • 1 回答
  • 0 关注
  • 152 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号