首页 > 编程问答 >Numpy:将掩码应用于值,然后取平均值,但并行

Numpy:将掩码应用于值,然后取平均值,但并行

时间:2024-07-24 05:20:45浏览次数:8  
标签:python arrays numpy mask

我有一个 1d numpy 值数组:

v = np.array([0, 1, 4, 0, 5])

此外,我有一个 2d numpy 布尔掩码数组(在生产中,有数百万个掩码):

m = np.array([
    [True, True, False, False, False],
    [True, False, True, False, True],
    [True, True, True, True, True],
])

我想将掩码中的每一行应用到数组 v ,然后计算屏蔽值的平均值。

预期行为:

results = []
for mask in m:
    results.append(np.mean(v[mask]))

print(results) # [0.5, 3.0, 2.0]

很容易按顺序执行,但我确信有一个漂亮的并行版本?我发现的一个解决方案:

mask = np.ones(m.shape)
mask[~m] = np.nan
np.nanmean(v * mask, axis=1) # [0.5, 3.0, 2.0]

是否还有另一种解决方案,也许使用 np.ma 模块?我正在寻找比我当前的两个解决方案更快的解决方案。


可以使用布尔索引和矩阵乘法的组合来实现这一点,而无需任何显式循环或掩码创建。以下是方法:

v = np.array([0, 1, 4, 0, 5])
m = np.array([
    [True, True, False, False, False],
    [True, False, True, False, True],
    [True, True, True, True, True],
])

# 计算每个掩码的 True 值的数量
counts = m.sum(axis=1, keepdims=True)

# 使用布尔索引执行矩阵乘法以获取每个掩码的总和
sums = (m * v).sum(axis=1, keepdims=True)

# 计算平均值
results = sums / counts

print(results) # [[0.5], [3. ], [2. ]]

让我们分解一下:

  1. counts = m.sum(axis=1, keepdims=True) :
  2. 这会计算 m 中每行的 True 值的数量(即,每个掩码中的有效元素数量)。
  3. axis=1 指定我们对行进行求和。
  4. keepdims=True 保留了维度,从而使 counts 成为一个列向量,便于广播。

  5. sums = (m * v).sum(axis=1, keepdims=True) :

  6. m * v 使用广播将 v 乘以 m 中的每一行。由于 m 是布尔值,因此这实际上会选择 v 中对应于 True 值的元素。
  7. (m * v).sum(axis=1, keepdims=True) 对每行求和,得到每个掩码的有效值之和,同时保持维度以实现广播。

  8. results = sums / counts :

  9. 最后,我们将每个掩码的总和除以每个掩码的计数,以获得平均值。广播用于按元素执行此操作。

这种方法利用了 NumPy 的矢量化操作和布尔索引,使其非常高效。它避免了显式循环和创建临时数组,例如的 nan 解决方案,使其在性能和内存使用方面可能更快。

标签:python,arrays,numpy,mask
From: 78785590

相关文章

  • 如何使用 Python 打开 Google Firestore 上的特定数据库?
    我正在使用Firebase并使用以下代码从Firestore设置/检索文档:importfirebase_adminfromfirebase_adminimportcredentials,firestorecred=credentials.ApplicationDefault()firebase_admin.initialize_app(cred,options={"projectId":"huq-jimbo"})fires......
  • 如何使用 Python 和 Numpy 重现 Matlab 文件读取以解码 .dat 文件?
    我有一个Matlab脚本,可以读取编码的.dat文件,对其进行解码并保存。我试图使用numpy将其转换为Python。我发现对于同一个文件,我得到不同的输出结果(python数字没有意义)。该代码最初作为从串行端口读取的脚本的一部分运行,因此是数据的结构。我首先认为位移是问题所在,因为......
  • 在Python中调整pdf页面大小
    我正在使用python裁剪pdf页面。一切正常,但如何更改页面大小(宽度)?这是我的裁剪代码:input=PdfFileReader(file('my.pdf','rb'))p=input.getPage(1)(w,h)=p.mediaBox.upperRightp.mediaBox.upperRight=(w/4,h)output.addPage(p)当我裁剪页面时,我也需要......
  • 如何使用 python 更改资源管理器窗口中的路径?
    没有人知道如何在不使用python打开新实例的情况下更改资源管理器窗口中的当前路径吗?例如,如果用户使用C:\Users\User打开资源管理器窗口。然后我必须将该路径更改为C:\Windows\System32例如。提前致谢。很遗憾,无法直接使用Python更改现有文件资源管理器窗口的......
  • python 以及将数组传递给函数的问题
    我需要求解一些常微分方程$\frac{dy}{dx}=f(x)=x^2ln(x)$并继续在限制0之间创建数组xpt。<=xpt<=2因为我必须小心xpt=0,所以我将函数定义如下deff(x):ifx<=1.e-6:return0.else:returnnp.square(x)*np.log(x)我的调用程序读取Np......
  • 如果 Python 脚本正在使用文件夹,如何在文件资源管理器中进行更改时防止 Windows 的“
    我有一个简单的脚本,显示在QTreeView中的QListView中选择的目录的内容,我想添加打开文件资源管理器的功能,以让用户编辑目录内的内容。但是,添加新的文件夹和文件可以,但删除或移动文件夹或文件会提示“文件夹正在使用”错误:此操作无法完成,因为该文件已在另一个程......
  • 如何使用 Python API 获取每个模型的活跃用户列表、最后登录信息
    我想通过PythonAPI获取我的dbt项目的所有模型中的活动或非活动用户列表。这可能吗?我尝试列出模型,但无法获取用户信息,如用户名、项目、以及上次活动或上次登录。不幸的是,dbt本身并不跟踪你所寻找的用户活动数据(最后登录、活跃用户等)。dbt的主要功能是转换数据,而不......
  • Python tkinter 窗口不断关闭,我不知道为什么
    我正在尝试制作一个有趣的小程序,其中每小时左右就会有一只毛茸茸的动物走过屏幕。我有一个主窗口,它启动一个循环,每小时左右播放一次动画/声音,但是在口袋妖怪第一次完成行走后,整个程序就会结束。我认为这可能与我设置tkinter窗口的方式有关,但我无法弄清楚。我认为在这里包含......
  • 用于自动访问 MongoDB Atlas CLI 的 Python 脚本
    我想编写一个Python脚本,以便普通用户可以访问他的数据库并从他的终端执行CRUD操作。我正在查看官方文档,但我有点迷失。有人可以给我指点基本教程来开始吗?当然,以下是如何构建Python脚本来访问MongoDBAtlasCLI的基本教程:先决条件:MongoDBAtlas......
  • Python实现简单学生登陆系统
     代码:importhashlibclassStudent:def__init__(self,username,password):#初始化学生对象,存储用户名和加密后的密码self.username=usernameself.password=hashlib.sha256(password.encode()).hexdigest()defcheck_passwo......