涉及填充位置的广播问题

2023-12-12

介绍

我有一个函数func这是可矢量化的,我使用它对其进行矢量化np.frompyfunc。而不是使用嵌套for循环,我只想调用它一次,因此我需要用以下内容填充输入np.newaxis's.

我的目标是摆脱两个嵌套for循环并使用numpy.array而是广播功能。

这是 MWEfor循环(我想摆脱 for 循环,而是填充变量c_0, c_1, rn_1, rn_2, and factor打电话时myfunc.

感兴趣问题的 MWE

for i, b_0 in enumerate(b_00):
    for j, b_1 in enumerate(b_11):
        factor = b_0 + b_1
        rn = (b_0 * coord + b_1 * coord2) / factor
        rn_1 = coord - rn
        rn_2 = coord2 - rn
        results = np.add( results,np.prod(myfunc(c_0[:,None,:], c_1[None,:,:], rn_1, rn_2, factor), axis=2) )

上面的显式 for 循环是正确的,并且包含在块代码中以保证质量。

我目前的努力

factor = b_00[:, None] + b_11[None, :]
rn = np.add( (b_00[:,None] * coord[None,:])[:, None, :],  (b_11[:,None] * coord2[None,:])[None, :, :] ) / factor[:,:,None]
rn_1 = coord - rn
rn_2 = coord2 - rn

results2 = np.prod(myfunc(c_0[:,None,:, None, None], c_1[None,:,:, None, None], rn_1[:,:,:],rn_2[:,:, :], factor[None,:, :, None]), axis=2)
results2 = np.squeeze(results2)
results2 = np.sum(results2, axis=(2,3))

整体代码块

    import numpy as np 

myfunc = np.frompyfunc(func,5,1)
################################################################
# Prep arrays needed for MWE
################################################################    
results = np.zeros((5,3))
coord = np.array([1,1,2])
coord2 = np.array([3,3,3])
c_0 = np.array([[0,0,2],[0,2,0],[2,0,0],[1,1,0], [1,0,1]])
c_1 = np.array([[0,0,2],[0,2,0],[2,0,0]])
b_00 = np.array([2.2, 1.1, 4.4]) # np.array([2.2, 3.3, 40.4])
b_11 = np.array([1.2, 3.3]) # np.array([1.2, 5.3])

################################################################
# This is only for comparison. `results` is the correct answer
################################################################
for i, b_0 in enumerate(b_00):
    for j, b_1 in enumerate(b_11):
        factor = b_0 + b_1
        rn = (b_0 * coord + b_1 * coord2) / factor
        rn_1 = coord - rn
        rn_2 = coord2 - rn
        results = np.add( results,np.prod(myfunc(c_0[:,None,:], c_1[None,:,:], rn_1, rn_2, factor), axis=2) )

################################################################
# Prep for broadcasting   (My attempt)
################################################################
factor = b_00[:, None] + b_11[None, :]
rn = np.add( (b_00[:,None] * coord[None,:])[:, None, :],  (b_11[:,None] * coord2[None,:])[None, :, :] ) / factor[:,:,None]
rn_1 = coord - rn
rn_2 = coord2 - rn

# The following all get the same *wrong* answer
# results2 = np.prod(myfunc(c_0[:,None,:,None, None], c_1[None,:,:, None, None], rn_1[:, None, None],rn_2[:,None, None], factor[None,:, :]), axis=2) 
# results2 = np.prod(myfunc(c_0[:,None,:, None, None, None], c_1[None,:,:, None, None, None], rn_1[None, None,:,:,:, None],rn_2[None, None,:,:, :, None], factor[None,:, :, None, None]), axis=2) 
# results2 = np.prod(myfunc(c_0[:,None,:, None, None], c_1[None,:,:, None, None], rn_1[None, None,:,:,:],rn_2[None, None,:,:, :], factor[None,:, :, None]), axis=2)

# this should be the only line needing work!
results2 = np.prod(myfunc(c_0[:,None,:, None, None], c_1[None,:,:, None, None], rn_1[:,:,:],rn_2[:,:, :], factor[None,:, :, None]), axis=2)

results2 = np.squeeze(results2)
results2 = np.sum(results2, axis=(2,3))

assert np.allclose(results, results2)

# Vectorized function to be sent broadcasted arrays
def func(r0, r1, x, y, at):
    val = 0.0 
    for i in range(r0+1):
        for j in range(r1+1):
            val += x + i*j + at * y
    return val

Problems

  1. 通过上面的代码,我得到了结果数组的正确形状(results2是我在广播方面的尝试,并且results是给出正确答案的缓慢 for 循环),但它有错误的值。
  2. As @hpaulj指出,如果我改变尺寸b_00如果长度为 4(或任何更大的长度),我的解决方案甚至无法获得正确的形状。

Update

请确保它适用于当前的b_00 = np.array([2.2, 1.1, 4.4])以及更一般的b_00 = np.array([2.2, 1.1, 4.4, 5.1, 6.2])。我想要一个广播解决方案,但会接受一个比实际解决方案更快的解决方案for loops.


这应该可以解决你的问题!

#Definitions
coord = np.array([1,1,2])
coord2 = np.array([3,3,3])
c_0 = np.array([[0,0,2],[0,2,0],[2,0,0],[1,1,0], [1,0,1]])
c_1 = np.array([[0,0,2],[0,2,0],[2,0,0]])
b_00 = np.array([2.2, 1.1, 4.4]) # np.array([2.2, 3.3, 40.4])
b_11 = np.array([1.2, 3.3]) # np.array([1.2, 5.3])

#Vectorized code for prep 
b_0 = np.outer(b_00, coord)
b_1 = np.outer(b_11, coord2)
factor = (b_00+b_11.reshape(-1,1)).T[:,:,None]
rn = np.divide((b_0[:,None]+b_1), factor)
rn_1 = coord-rn
rn_2 = coord2-rn

#THIS IS YOUR INTERESTING PART
results = np.prod(myfunc(c_0[:,None,:,None,None], c_1[None,:,:,None,None], rn_1.transpose(2,0,1), rn_2.transpose(2,0,1), factor.transpose(2,0,1)).transpose(3,4,0,1,2), axis=4)
results = np.add.reduce(results, axis=(0,1))
results
array([[6707.793061061082, 5277.838468285241, 5277.838468285241],
       [5277.838468285241, 5992.8157646731615, 5277.838468285241],
       [5277.838468285241, 5277.838468285241, 5992.8157646731615],
       [7037.117957713655, 7513.7694886389345, 7513.7694886389345],
       [7990.421019564216, 7037.117957713655, 7513.7694886389345]],
      dtype=object)

仅出于理解目的,由于在旧的循环解决方案中,myfunc 在 rn_1 和 rn_2 的第一个轴上运行,因此广播通道需要是最后 2 个而不是第一个。因此,我在 c_0 和 c_1 的末尾添加 2 个通道,然后将最后一个轴放在前面,使 (3,2,3) rn_1 变为 (3,3,2)。对于因子也是如此。所以现在 myfunc 可以对突出显示广播频道的张量进行操作 - (5,1,3,1,1), (1,3,3,1,1), (3,3,2), (3,3,2), (1,3,2)

最后,我再次转置,将广播频道放在前面,这样我们就有了(3,2,5,3,3) 形状张量,其中前 2 个通道是 3,2 嵌套循环的广播版本,而 5,3,3 是您现在需要在 axis = 4 而不是 axis = 2 上 np.prod 的矩阵。

之后,使用 np.add.reduce 在 0,1 轴上求和,将结果带到 5,3 矩阵,这是一个简单的问题。最终的结果应该和循环的结果完全相同。

我也冒昧地修改了第一部分,因为这对我的眼睛来说更舒服,但请随意忽略该部分。

附言。检查它是否可以无缝地用于您提到的示例

b_00 = np.array([2.2, 1.1, 4.4, 5.1, 6.2])
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

涉及填充位置的广播问题 的相关文章

随机推荐

  • 用于命令行脚本的 Cookbook GUI 界面

    我有一个命令行 Python 脚本 可以很好地在给定一些参数的情况下将一种文件转换为另一种文件 现在我想将其部署给我的一些可能不知道命令行是什么的同事 我可以花几个小时来尝试确定哪个 Python GUI 工具包是 最好的 然后学习如何做我
  • 使用随时间变化的任意布尔条件过滤 Touch.FrameReported IObservable

    我一直在尝试 Windows Phone 7 中的响应式扩展 RX 并且非常接近可行的解决方案 但遇到了一个小细节 我正在尝试使用处理原始触摸事件Touch Frame报告 and Observable FromEvent 有点教育追求 更
  • dagger2 和 kotlin 的 Android 单元测试问题

    我试图在 android 的测试文件夹中创建一个 dagger 组件接口 但是在 Dagger 完成生成的类后 它显示错误 无法访问 TestComponent 它是 com example animals di DaggerTestApp
  • 如何创建winform登录对话框并保持循环

    创建一个登录表单 如果凭据正确 该登录表单将进入主表单 这是基本的伪代码 ShowLoginForm if DialogResult OK CheckCredentials if credentials VALID ShowMainForm
  • CSV 文件未在 WordPress 中上传

    我无法在 WordPress 网站上上传 CSV 文件 错误 抱歉 出于安全原因不允许使用此文件类型 检查下图 网站链接 我相信 错误中清楚地提到了所有内容 并且您也强调了这一点 出于安全原因不允许使用此文件类型 要解决此问题 请在 wp
  • 有什么方法可以跟踪 proc 宏中发生错误的位置吗?

    我正在实现一个 proc 宏 并在另一个板条箱中进行测试 当我编译客户端包时 proc 宏的调用站点抛出错误 error proc macro panicked gt foo src main rs 17 1 该错误发生在 proc 宏实现
  • 基于上下文的实体框架的不同连接字符串

    我有一个使用实体框架的 Web 表单应用程序 该应用程序部署在开发盒 我的本地计算机和生产盒上 其中每个都有不同的连接字符串 处理这个问题的最佳方法是什么 我使用 TFS 构建服务器部署到开发环境 并将构建结果压缩并手动将其复制到生产环境
  • 如何在 MapView 上创建动态编号的 Pin 指针?

    我想在我的设备上显示一些位置MapView 这些位置将显示具有数字 1 2 3 等的图钉 类似于 Google 地图结果 但它是 A B C 我认为拥有所有数字的引脚是不可行的 有什么方法可以让我创建一个带有 pin 背景的布局TextVi
  • python multiprocess.Pool 在标准输出中按顺序显示结果

    在 multiprocessing Pool 中 我试图以相同的顺序显示我的打印结果 from multiprocessing import Pool import time def func arg time sleep 0 001 pr
  • 尝试提供 Meteor 应用程序时出现“babel-runtime”错误

    我最近开始使用 Meteor 和 React 我跟着tutorial在 Meteor 网站上没有问题 然后我尝试创建另一个项目 尝试遵循另一个项目tutorial 对于旧版本的 Meteor 在这个过程中 Meteor 开始抛出一些难以理解
  • 如何使用项目反应器实现调用重复,直到满足特定条件?

    有没有什么方法可以使用项目反应器来做这样的事情 fetchSystemUpdates return Mono
  • 过滤 IQueryable 子列表

    使用实体框架 但这可能无关紧要 如果我有一个 Iqueryable 如何过 滤子列表并使其保持 IQueryable 这样它就不会到达数据库 如果我有 10 个项目 每个项目有 3 个子项目 如何过滤它以便返回所有 10 个项目 并且它们的
  • IE9 中简单模式的问题

    昨天我推出了一个新网站 在将文件上传到服务器之前 我在 IE8 Firefox Safari 和 Chrome 中测试了该网站 一切似乎都正常 但我刚刚安装了IE9简单模态此浏览器中不显示框 我正在使用以下 JavaScript 代码 jQ
  • 用于过滤 Google 表格中具有最高值的唯一行的公式

    我有一张工作表 可以每天多次自动从多个帐户中提取社交指标 因此我经常有同一个帖子的多行数据 如何过滤新工作表中的行 以便每个唯一帖子仅保留展示次数最高 G 列 的帖子 ID F 列 我想要的过滤结果 我已经探索了查询 不是我的强项 和过滤公
  • ASP.NET MVC 中的 Cookie 管理

    我想在 ASP net MVC 中向 cookie 添加一些内容 处理 cookie 或更多 cookie 中所有内容的最佳方法是什么 在asp net mvc中处理cookie有什么好方法吗 这是一个例子 public class Hom
  • 日期范围 Google 图表工具

    我正在尝试使用 Google Charts 在折线图上显示数据 数据显示正常 但我想设置要显示的日期范围 数据以 JSON 文字格式从数据库发送 cols label Week type date label Speed type numb
  • GWT Cell树,如何使用?

    有人可以解释一下如何使用 GWT 单元树吗 我正在尝试谷歌搜索 但没有找到任何有价值的教程 Thanks Try 谷歌示例 1 包括 onModuleLoad 方法
  • 在 Windows XP 下运行 Python 二进制文件

    我将 PySide 应用程序编译为 x32 和 x64 模式 并且它可以在 Windows 7 下工作 但是我发现该应用程序无法在Windows XP下启动 我应该在规范文件中另外使用一些技巧吗 当前的 PyInstaller 脚本在 ap
  • 如何在Excel中使用VBA截断数字而不是四舍五入?

    我需要创建一个表 操作员可以在其中输入数字 这是受保护的工作表 因此操作员无法更改任何内容 他们只能在特定单元格中输入数字 适用于 Mac 的 Microsoft 365 我需要 Excel 显示 2 位小数而不进行四舍五入 例如 对于 3
  • 涉及填充位置的广播问题

    介绍 我有一个函数func这是可矢量化的 我使用它对其进行矢量化np frompyfunc 而不是使用嵌套for循环 我只想调用它一次 因此我需要用以下内容填充输入np newaxis s 我的目标是摆脱两个嵌套for循环并使用numpy