我可以在此计算中消除所有Python循环:
result[i,j,k] = (x[i] * y[j] * z[k]).sum()
Run Code Online (Sandbox Code Playgroud)
其中x[i],y[j],z[k]是长度的矢量N和x,y,z具有第一长度尺寸A,B,CST输出是形状(A,B,C)和各元件是三重产物(逐元素)的总和.
我可以从3到1循环(下面的代码)得到它,但我试图消除最后一个循环.
如果有必要,我可以A=B=C(通过少量填充).
# Example with 3 loops, 2 loops, 1 loop (testing omitted)
N = 100 # more like 100k in real problem
A = 2 # more like 20 in real problem
B = 3 # more like 20 in real problem
C = 4 # …Run Code Online (Sandbox Code Playgroud) 我如何对这个循环进行矢量化,这个循环使用numpy数组填充更大矩阵的两个正方形子矩阵(也保持更大的矩阵对称):
for x in range(n):
assert m[x].shape == (n,)
M[i:i+n,j+x] = m[x]
M[j+x,i:i+n] = m[x]
Run Code Online (Sandbox Code Playgroud)
这很诱人,但不同意上面的循环(参见下面的示例分歧):
assert m.shape == (n,n)
M[i:i+n,j:j+n] = m
M[j:j+n,i:i+n] = m
Run Code Online (Sandbox Code Playgroud)
这是一个小例子(n> 1崩溃):
from numpy import arange,empty,NAN
from numpy.testing import assert_almost_equal
for n in (1,2,3,4):
# make the submatrix
m = (10 * arange(1, 1 + n * n)).reshape(n, n)
N = n # example below, submatrix is the whole thing
# M1 using loops, M2 "vectorized"
M1 = empty((N, N))
M2 = empty((N, N)) …Run Code Online (Sandbox Code Playgroud) 假设我想制作2+个热图(在相同或不同的图上)并且颜色< - >值映射在它们之间是相同的.
默认情况下,colormap中的极值(比如jet)将单独用于每个热图的动态范围(即每次调用imshow),并且我想强制映射相同,即使用全局动态范围.
我认为一个等价的陈述是我想以某种方式指定绝对映射,而给定cmap对象的imshow的行为是相对于输入的动态范围.
numpy.interp非常方便,相对较快.在某些情况下,我想将其输出与稀疏值传播的非插值变量(在"密集"输出中)进行比较,结果在稀疏输入之间是分段常数.我想要的函数也可以称为"稀疏 - >密集"转换器,它复制最新的稀疏值,直到它找到一个较晚的值(一种空插值,好像零时间/距离从前一个值开始经过).
不幸的是,调整源代码并不容易,numpy.interp因为它只是编译函数的包装器.我可以使用Python循环自己编写,但希望找到一种C-speed方法来解决问题.
更新:下面的解决方案(scipy.interpolate.interp1dwith kind='zero')非常慢,每次调用需要10秒以上(例如输入500k的长度,即50%填充).它kind='zero'使用零阶样条实现,调用spleval非常慢.但是,kind='linear'(即默认插值)的源代码为使用直接numpy解决问题提供了一个很好的模板(最小化更改是设置slope=0).该代码显示了如何使用numpy.searchsorted来解决问题,并且运行时类似于调用numpy.interp,因此通过调整scipy.interpolate.interp1d线性插值的实现来跳过插值步骤(斜率!= 0混合相邻值)来解决问题.
我想像numpy.arange(0, cnt_i)一个cnt值向量一样对调用进行向量化,并像这个片段一样连接结果:
import numpy
cnts = [1,2,3]
numpy.concatenate([numpy.arange(cnt) for cnt in cnts])
array([0, 0, 1, 0, 1, 2])
Run Code Online (Sandbox Code Playgroud)
不幸的是,由于临时数组和列表推导循环,上面的代码非常低效.
有没有办法在numpy中更有效地做到这一点?
有没有人知道(常见情况)快于线性的方法来查找数组的布尔属性的端点.
例如,numpy.nonzero(a)[0] [ - 1]是(dimension = 0)的最后一个非零元素的索引,类似地,numpy.nonzero(a)[0] [0]是索引.第一个非零元素.
如果我们知道我们只关心第一个或最后一个元素,那么我们可以使用更少的内存并且具有比上面运行"非零"更好的公共情况运行时.例如,如果我们坚持线性搜索,我们至少可以从适当的一端开始(向后搜索以找到与条件匹配的最后一个值).或者我们可以使用二进制搜索(例如,如果中间元素匹配条件,我们不需要检查上半部分以找到它的真实的最后一个元素).这似乎很普遍,可能有一个现有的实现,但我没有找到类似的东西.
这是一种特殊的有损压缩,很容易在numpy中实现.
我原则上可以直接比较原始(float64)和重建(float64(float32(原始))并知道最大错误之类的事情.
除了查看我的实际数据的最大误差之外,是否有人知道这会产生什么类型的失真,例如作为原始值的大小的函数?
我会更好地将所有值(以64位为单位)映射到首先说[-1,1](作为极值的一小部分,可以保留在64位中)以利用更接近零的浮点密度?
我正在添加一个我想到的具体案例.假设我有500k到1e6的值,范围从-20到20,大约是IID~Normal(mu = 0,sigma = 4),所以它们已经非常集中在零附近,而"20"是〜5-sigma罕见.让我们说它们是科学测量,其中真正的精度比64位浮点数少很多,但很难确切地知道.我有大量单独的实例(可能是TB的价值),因此压缩具有很多实用价值,而float32是获得50%的快速方法(如果有的话,通过gzip等额外的无损压缩更好地工作).所以"-20到20"消除了很多关于真正大值的担忧.
我有一系列的形状(n,t),我想把它当作时间序列n-vectors.
我想知道每个唯一向量的唯一n-vector值t-dimension以及相关t-indices的值.我很乐意使用任何合理的平等定义(例如numpy.unique将采用浮点数)
使用Python循环很容易,t但我希望采用矢量化方法.
在某些特殊情况下,可以通过折叠来完成n-vectors入标量(以及使用numpy.unique上的1D结果),例如,如果你有布尔你可以使用矢量dot与(2**k)转换(布尔向量)为整数向量,但我在寻找相当普遍的解决方案.