这是对 this answer 的跟进我之前的问题 Fastest approach to read thousands of images into one big numpy array .
在 chapter 2.3 "Memory allocation of the ndarray" ,Travis Oliphant 写了以下关于如何在内存中访问 C 有序 numpy 数组的索引。
...to move through computer memory sequentially, the last index is incremented first, followed by the second-to-last index and so forth.
这可以通过沿两个第一个或两个最后一个索引对二维数组的访问时间进行基准测试来确认(出于我的目的,这是加载 500 个大小为 512x512 像素的图像的模拟):
import numpy as np
N = 512
n = 500
a = np.random.randint(0,255,(N,N))
def last_and_second_last():
'''Store along the two last indexes'''
imgs = np.empty((n,N,N), dtype='uint16')
for num in range(n):
imgs[num,:,:] = a
return imgs
def second_and_third_last():
'''Store along the two first indexes'''
imgs = np.empty((N,N,n), dtype='uint16')
for num in range(n):
imgs[:,:,num] = a
return imgs
基准测试
In [2]: %timeit last_and_second_last()
136 ms ± 2.18 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [3]: %timeit second_and_third_last()
1.56 s ± 10.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
到目前为止一切顺利。但是,当我沿最后一个维度和倒数第三个维度加载数组时,这几乎与将它们加载到最后两个维度一样快。
def last_and_third_last():
'''Store along the last and first indexes'''
imgs = np.empty((N,n,N), dtype='uint16')
for num in range(n):
imgs[:,num,:] = a
return imgs
基准测试
In [4]: %timeit last_and_third_last()
149 ms ± 227 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
last_and_third_last()我的速度如此接近last_and_second_last()相比 second_and third_last() ?最佳答案
我将尝试说明索引,而不涉及处理器缓存等细节。
让我们创建一个具有不同元素值的小型 3d 数组:
In [473]: X = np.mgrid[100:300:100,10:30:10,1:4:1].sum(axis=0)
In [474]: X
Out[474]:
array([[[111, 112, 113],
[121, 122, 123]],
[[211, 212, 213],
[221, 222, 223]]])
In [475]: X.shape
Out[475]: (2, 2, 3)
ravel 将其视为一维数组,并向我们展示值在内存中的布局方式。 (顺便说一下,这是默认的 C 排序)
In [476]: X.ravel()
Out[476]: array([111, 112, 113, 121, 122, 123, 211, 212, 213, 221, 222, 223])
当我在第一个维度上建立索引时,我得到 2*3 值,即上述列表的连续 block :
In [477]: X[0,:,:].ravel()
Out[477]: array([111, 112, 113, 121, 122, 123])
在最后一个索引上给出 4 个值,从整个数组中选择 - 我添加了 .. 以突出显示它
In [478]: X[:,:,0].ravel()
Out[478]: array([111,.. 121,.. 211,.. 221])
中间的索引给了我 2 个连续的子 block ,即 2 行 X。
In [479]: X[:,0,:].ravel()
Out[479]: array([111, 112, 113,.. 211, 212, 213])
通过 strides 和 shape 计算 numpy 可以访问 X 中的任何一个元素(关于)同时。在 X[:,:,i] 的情况下,这就是它必须做的。这 4 个值“分散”在数据缓冲区中。
但如果它可以访问连续的 block ,例如在 X[i,:,:] 中,它可以将更多的操作委托(delegate)给低级编译和处理器代码。使用 X[:,i,:] 时,这些 block 没有那么大,但可能仍然大到足以产生重大影响。
在您的测试用例中,[n,:,:] 在 512*512 元素 block 上迭代 500 次。
[:,n,:] 必须将该访问分成 512 个 block ,每个 block 512 个。
[:,:,n] 必须进行 500 x 512 x 512 次单独的访问。
我想知道使用 uint16 是否会夸大效果。在另一个问题中,我们刚刚展示了使用 float16 的计算要慢得多(高达 10 倍),因为处理器(和编译器)被调整为使用 32 位和 64 位数字。如果处理器被调整为移动 64 位数字 block ,那么移动一个隔离的 16 位数字可能需要大量额外的处理。这就像从文档中逐字复制粘贴一样,而逐行复制每次复制所需的击键次数更少。
确切的细节隐藏在处理器、操作系统和编译器以及 numpy 代码中,但希望这能让您了解为什么您的中间情况更接近最优而不是最坏的情况。
在测试中 - 将 imgs 设置为 a.dtype 在所有情况下都会减慢速度。所以 'uint16' 不会引起任何特殊问题。
Why does `numpy.einsum` work faster with `float32` than `float16` or `uint16`?
关于python - 与倒数第二个相比,最后一个索引对 numpy 数组的访问时间的影响更大,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44115571/
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta
我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何
我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>
我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah
我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以
如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象
关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion为什么SecureRandom.uuid创建一个唯一的字符串?SecureRandom.uuid#=>"35cb4e30-54e1-49f9-b5ce-4134799eb2c0"SecureRandom.uuid方法创建的字符串从不重复?
我有一个正在构建的应用程序,我需要一个模型来创建另一个模型的实例。我希望每辆车都有4个轮胎。汽车模型classCar轮胎模型classTire但是,在make_tires内部有一个错误,如果我为Tire尝试它,则没有用于创建或新建的activerecord方法。当我检查轮胎时,它没有这些方法。我该如何补救?错误是这样的:未定义的方法'create'forActiveRecord::AttributeMethods::Serialization::Tire::Module我测试了两个环境:测试和开发,它们都因相同的错误而失败。 最佳答案