我正在尝试使用'values'数组和'counter'数组将多个值插入到数组中.例如,如果:
a=[1,3,2,5]
b=[2,2,1,3]
Run Code Online (Sandbox Code Playgroud)
我想要一些功能的输出
c=somefunction(a,b)
Run Code Online (Sandbox Code Playgroud)
成为
c=[1,1,3,3,2,5,5,5]
Run Code Online (Sandbox Code Playgroud)
其中a(1)重复b(1)次,a(2)重复b(2)次等等...
MATLAB中是否有内置函数来执行此操作?如果可能的话,我想避免使用for循环.我尝试过'repmat()'和'kron()'的变体无济于事.
这基本上是Run-length encoding.
在Python中矢量化for循环是什么意思?有没有其他方法来编写嵌套的for循环?
我是Python的新手,在我的研究中,我总是遇到NumPy库.希望可以有人帮帮我.
创建使用的函数时strsplit,矢量输入的行为不符合要求,sapply需要使用.这是由于产生的列表输出strsplit.有没有办法对流程进行矢量化 - 也就是说,函数会在列表中为输入的每个元素生成正确的元素?
例如,要计算字符向量中单词的长度:
words <- c("a","quick","brown","fox")
> length(strsplit(words,""))
[1] 4 # The number of words (length of the list)
> length(strsplit(words,"")[[1]])
[1] 1 # The length of the first word only
> sapply(words,function (x) length(strsplit(x,"")[[1]]))
a quick brown fox
1 5 5 3
# Success, but potentially very slow
Run Code Online (Sandbox Code Playgroud)
理想情况下,像length(strsplit(words,"")[[.]])where 这样的东西.被解释为输入向量的相关部分.
我有一个非常大的列表X和一个矢量化函数f.我想计算f(X),但如果我用一个核心来做这个将需要很长时间.我有(访问)48核服务器.并行计算的最简单方法是f(X)什么?以下不是正确的答案:
library(foreach)
library(doMC)
registerDoMC()
foreach(x=X, .combine=c) %dopar% f(x)
Run Code Online (Sandbox Code Playgroud)
上面的代码确实会对计算进行并行化f(X),但它会通过f单独应用于每个元素来实现X.这忽略了矢量化的性质,f并且可能会使事情变慢,而不是更快.而不是应用felementwise X,我想X分成合理大小的块并应用于f那些.
那么,我应该手动拆分X成48个相等大小的子列表然后f并行应用于每个子列表,然后手动将结果放在一起?或者是否有为此设计的包装?
如果有人想知道,我的具体用例就在这里.
给定一个a包含不等长度向量的列表和一个b包含来自向量的元素的向量的列表a,我想得到一个等长的向量来b包含匹配a元素的索引b(这是我所知道的一个不好的解释)...
以下代码完成了这项工作:
a <- list(1:3, 4:5, 6:9)
b <- c(2, 3, 5, 8)
sapply(b, function(x, list) which(unlist(lapply(list, function(y, z) z %in% y, z=x))), list=a)
[1] 1 1 2 3
Run Code Online (Sandbox Code Playgroud)
sapply当然,用for循环替换也可以实现相同的目的
问题是这个代码将用于长度大于1000的列表和向量.在现实生活中,该函数大约需要15秒(for循环和for sapply).
有没有人知道如何加快速度,对并行方法安全?我没有看到矢量化方法(我不能用C编程,尽管这可能是最快的).
编辑:
只会强调Aaron使用match()的优雅解决方案,其速度提升1667次(从15到0.009)
我在它上面扩展了一下以允许多个匹配(返回是一个列表)
a <- list(1:3, 3:5, 3:7)
b <- c(3, 5)
g <- rep(seq_along(a), sapply(a, length))
sapply(b, function(x) g[which(unlist(a) %in% x)])
[[1]]
[1] 1 2 3
[[2]]
[1] 2 3
Run Code Online (Sandbox Code Playgroud)
这个的运行时间是0.169,这可能相当慢,但另一方面更灵活
我有两个向量,idx1并且idx2,我想获得它们之间的值.如果idx1和idx2是数字,而不是载体,我能做到这一点的方式如下:
idx1=1;
idx2=5;
values=idx1:idx2
% Result
% values =
%
% 1 2 3 4 5
Run Code Online (Sandbox Code Playgroud)
但在我的情况下,idx1并且idx2是可变长度的向量.例如,对于length = 2:
idx1=[5,9];
idx2=[9 11];
Run Code Online (Sandbox Code Playgroud)
我可以使用冒号运算符直接获取其间的值吗?这是类似于以下内容:
values = [5 6 7 8 9 9 10 11]
Run Code Online (Sandbox Code Playgroud)
我知道我可以做idx1(1):idx2(1)和idx1(2):idx2(2),这是单独提取各列的值,因此,如果没有其他的解决方案,我可以用一个for循环做到这一点,但也许Matlab的可以更容易地做到这一点.
是否存在依赖于隐式向量化的编程语言或语言扩展?
对于标量C代码的单/双精度的SSE4.1,AVX,AVX2(有或没有FMA3/4),我需要做出积极的假设来生成良好的DLP /向量化代码.
在过去的10年里,我依靠英特尔的内在函数来编写我的HPC内核,并明确地进行了矢量化.与此同时,我经常对C/C++编译器(GCC,clang,LLVM等)生成的DLP代码的质量感到失望,如果你问,我可以发布具体的例子.
从内在指南来看,很明显,为现代平台编写带有内在函数的"手动"HPC内核不再是一个可持续的选择,除非我有一大批程序员.太多版本和组合:SSE4.1,AVX,AVX2,AVX512 +口味,FMA,SP,DP,半精度?如果我的目标平台是2012年以来最普遍的平台,那就不可持续了.
我最近尝试过针对OpenCL(CPU)的英特尔离线编译器.我编写了内核"a la CUDA"(即标量代码,隐式向量化),令我惊讶的是生成的程序集非常好地矢量化了!(Skylake,SP中的AVX2 + FMA)我遇到的唯一限制是缺少内置的数据缩减/互通通信功能,而不依赖于共享内存(可转换为CPU水平添加或shuffle + min/max操作) .
正如clemens和sschuberth所指出的那样,离线编译器并不是真正的解决方案,除非我不完全接受OpenCL.或者我破解我的调用者代码以遵守生成的程序集的调用约定,其中包括我不需要的参数,例如ndrange.完全接受OpenCL对我来说也不是一个选择,因为对于TLP我依赖于OpenMP和Pthreads(对于ILP,我依赖于硬件).
首先,值得回顾一下隐式矢量化和自动矢量化并不是一回事.事实上,我对自动向量化失去了希望(如上所述).不在隐式矢量化中.
下面的答案之一是要求一些代码示例. 这里我提供了一个内核的代码示例,该内核在三维结构块上实现NSE对流项的三阶逆风方案.值得一提的是,这代表了一个 简单的例子,因为不需要SIMD通道间合作/通信.
我有一个大的矩阵A,它是1GB的双倍值,当我将它重塑为不同的尺寸时,它的速度令人难以置信.
A=rand(128,1024,1024);
tic;B=reshape(A,1024,128,1024);toc
Elapsed time is 0.000011 seconds.
Run Code Online (Sandbox Code Playgroud)
怎么这么快?另一个观察结果是,运行该代码并存储两个1GB的矩阵后,MATLAB使用的内存少于应有的内存:Memory used by MATLAB: 1878 MB (1.969e+09 bytes)
我有np矩阵,我想将其转换为3d数组,其中元素的热编码为第三维.有没有办法处理没有循环每一行,例如
a=[[1,3],
[2,4]]
Run Code Online (Sandbox Code Playgroud)
应该做成
b=[[1,0,0,0], [0,0,1,0],
[0,1,0,0], [0,0,0,1]]
Run Code Online (Sandbox Code Playgroud) 我需要进行时间序列计算,其中每行计算的值取决于前一行中计算的结果.我希望使用方便data.table.实际问题是水文模型 - 累积水量平衡计算,在每个时间步骤增加降雨量,减去径流和蒸发量作为当前水量的函数.数据集包括不同的盆地和场景(组).在这里,我将使用更简单的问题说明.
对于每个时间步(行),计算的简化示例如下所示i:
v[i] <- a[i] + b[i] * v[i-1]
Run Code Online (Sandbox Code Playgroud)
a并且b是参数值的向量,并且v是结果向量.对于第一行(i == 1)的初始值v取为v0 = 0.
我首先想到的是使用shift()在data.table.最小的例子,包括期望的结果v.ans,是
library(data.table) # version 1.9.7
DT <- data.table(a = 1:4,
b = 0.1,
v.ans = c(1, 2.1, 3.21, 4.321) )
DT
# a b v.ans
# 1: 1 0.1 1.000
# 2: 2 0.1 2.100
# 3: 3 0.1 3.210
# …Run Code Online (Sandbox Code Playgroud) vectorization ×10
r ×4
matlab ×3
numpy ×2
python ×2
arrays ×1
c ×1
colon ×1
data.table ×1
hpc ×1
indexing ×1
list ×1
matrix ×1
octave ×1
opencl ×1
optimization ×1
performance ×1
python-3.x ×1
repeat ×1
strsplit ×1
time-series ×1
vector ×1