向量化包含迭代器的for循环numpy数组

如何解决向量化包含迭代器的for循环numpy数组

我试图通过利用Numpy中的矢量化功能来使python函数更快地运行。

函数的目的是在for循环的每次迭代结束时,位置arr [i,0](即每行的第一项)将包含2D数组(数据)中的行数,如果位置0处的值小于或等于该值或数组i

ans += map.getorDefault((int) (sq/v),0);

我当前正在使用for循环。运行时非常慢,因为它正在机器学习算法中使用。有人告诉我可以通过向量化for循环来进一步改善这一点。

在尝试使用列表理解功能时,我已经尝试过:

# Data is a 2D array
def function(data)
    n = len(data)
    arr = np.zeros(shape=(n,9))
    for i,sample in enumerate(data):
        arr[i][0] = np.count_nonzero(data[:,0] <= data[i][0])

但是我收到一个生成错误

arr[:,0] = ( np.count_nonzero(data[:,x] >  data[i][x]) for i in gini_arr[:,0] )

如何将其向量化为for循环?

解决方法

在对我的初始解决方案的评论中,您写道:在第0列中,否 元素小于0 。因此,我得出一个结论,即 您的职能应该是 ,而不是

另一个奇怪的地方是您使用控件之一创建了一个循环 名为 sample 的变量,但您永远不要使用此变量。 一个更自然的解决方案是遍历 range(n)(您计算出 n 之前,作为 data 中的行数)。

要在代码中更正的最后一个细节是您的函数 什么都不会退回。

一项改进:在计算满足以下条件的元素的数量时 在某些情况下,根据定义,结果是一个 integers 数组, 不是 float

因此,您的函数的更正内容(使用旧方法) 应该是:

def function(data):
    n = len(data)
    arr = np.zeros((n,9),dtype=int)
    for i in range(n):
        arr[i,0] = np.count_nonzero(data[:,0] < data[i,0])
    return arr

如何以矢量化方式计算结果

将函数定义为:

def fn(data):
    dd = data[:,0]  # The first column
    res = np.less(dd[np.newaxis,:],dd[:,np.newaxis]).sum(axis=1)
    return np.hstack([res[:,np.newaxis],np.zeros((dd.size,8),dtype=int)])

请注意, res 1-D 数组)包含以下内容的比较结果: dd 中的每个元素以及 dd 中的所有元素。

最终结果产生于:

  • res 转换为具有单列的数组
  • 由8列填充为零的“加法”。

要测试此功能,我创建了一个测试数组:

data = np.arange(25).reshape(5,-1)
data[3,0] = 1

包含以下内容:

array([[ 0,1,2,3,4],[ 5,6,7,8,9],[10,11,12,13,14],[ 1,16,17,18,19],[20,21,22,23,24]])

然后我跑fn(data)得到了

array([[0,0],[2,[3,[1,[4,0]])

对于上述测试数据(5行),我的函数仅计算了5%的速度 (您的107 µs和我的101 µs)。

但是对于更多行,例如60,您的功能完成 在1.24毫秒内,而我的功能在165微秒内,所以快了7倍。

对于更大的行数,我的代码的优点应该是 更明显。

按照截至2020-09-07的评论进行编辑

np.newaxis 工作原理的说明:

  1. dd(在 fn 函数中)包含array([ 0,5,10,20])- data 的第一列,但这是一个 1-D 数组。

  2. dd[np.newaxis,:]是一个 2-D 数组,包含相同的数组 单个中的数字:array([[ 0,20]])

  3. dd[:,np.newaxis]也是 2-D 数组,但这一次 相同的数字是单个的内容:

    array([[ 0],[ 5],[10],[ 1],[20]])
    
  4. 现在运行np.less(dd[np.newaxis,np.newaxis]).astype(int) (为便于评估已计算的内容,我补充说 转换为 int ):

    array([[0,0]])
    

    上面的结果是一个 2-D 数组,比较的结果 ( left_argument ),其中:

    • 行号是“行参数”中元素的数量,
    • 列号是元素“列参数”的数目。

    所以整个数组是“每个”比较的结果。

    示例:行( 0 )中的第一个元素不少于 列的元素,因此结果的第一行包含 全零。

  5. 最后一步是 sum(axis = 1),即计算上述总和 沿着每一行排列。

这样,最终结果是:array([0,4]),它将是 fn 函数的整个结果的第一列。

如果您仍然需要更多说明,请在网上搜索 np.newaxis 。 即使在SO上,您也可以找到很多关于此问题的解释。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?