我们目前正在开发一个 python 项目,由于性能限制,必须进行大量矢量化。我们最终进行了以下计算:我们有两个形状为 numpy 的数组,(20,6)并且想要计算行的成对点积,即我们最终应该获得一个(20,1)矩阵,其中每一行都是通过相应的向量点乘获得的标量.
非常基本的问题:
假设我有一个包含 5 个元素的一维 numpy 数组 (A):
A = np.array([ -4.0, 5.0, -3.5, 5.4, -5.9])
我需要向 A 的所有小于零的元素添加 5。没有 for 循环的 numpy 方法是什么?
鉴于此示例数据帧:
date;close;signal;positions
2017-01-02;27.90;0.0;0.0
2017-01-03;27.76;0.0;0.0
2017-01-04;28.65;1.0;1.0
2017-01-05;28.72;1.0;0.0
2017-01-06;28.00;1.0;0.0
2017-01-09;27.03;1.0;0.0 # <<<--- Note the price is -5% when compared to 28.65 (in 2017-01-04)
2017-01-10;28.26;1.0;0.0
2017-01-11;28.35;0.0;-1.0 # <<-- Sell
2017-01-12;29.12;0.0;0.0
2017-01-13;28.99;0.0;0.0
2017-01-16;28.50;1.0;1.0
2017-01-17;28.45;1.0;0.0
2017-01-18;29.06;1.0;0.0
2017-01-19;28.74;0.0;-1.0
2017-01-20;28.76;0.0;0.0
2017-01-23;29.50;0.0;0.0
2017-01-24;29.12;1.0;1.0
2017-01-25;29.87;1.0;0.0
2017-01-26;27.22;1.0;0.0 # <<<--- Note the price is -5% when compared to 29.12 (in 2017-01-24)
2017-01-27;29.76;1.0;0.0 # <<-- still holding the position...
Run Code Online (Sandbox Code Playgroud)
我想在价格低于 5% 时实施“止损”。在这种情况下,DataFrame 应如下所示:
date;close;signal;positions
2017-01-02;27.90;0.0;0.0
2017-01-03;27.76;0.0;0.0
2017-01-04;28.65;1.0;1.0 # <<-- Buy
2017-01-05;28.72;1.0;0.0
2017-01-06;28.00;1.0;0.0
2017-01-09;27.03;0.0;-1.0 # <<-- Sell with stop-loss
2017-01-10;28.26;0.0;0.0
2017-01-11;28.35;0.0;0.0
2017-01-12;29.12;0.0;0.0
2017-01-13;28.99;0.0;0.0 …Run Code Online (Sandbox Code Playgroud) 假设我有一个 numpy 数组:
array = np.array(['Fe', 'Pt', 'Ce', 'Nd', 'Pt', 'Fe', ..., 'Pt', 'Ce', 'Fe', 'Fe'])
Run Code Online (Sandbox Code Playgroud)
其中数组中的每个条目都是“Fe”、“Pt”、“Ce”或“Nd”。我了解如何获取单个条目的百分比,例如:
percentage = np.sum(array = 'Fe')/array.shape[0]*100
Run Code Online (Sandbox Code Playgroud)
但是,如果我想获取每个唯一字符串值的百分比怎么办?有没有一种方法可以向量化该操作并将其概括为任意数量的唯一字符串值?
理想情况下我想要这样的东西:
percentages = np.some_operation(array)
Run Code Online (Sandbox Code Playgroud)
它产生如下输出:
percentages = {'Fe': 25, 'Pt': 15, 'Nd': 45, 'Ce': 15}
Run Code Online (Sandbox Code Playgroud)
它不一定是字典的形式,只要清楚哪个百分比属于哪个元素即可。我打算处理的数组长度可能为 1,000 到 1,000,000 个条目。
假设我有一些数据,其中有多个数据点,其中一些数据点共享一个组标识符:
group <- rep(c(1:5), times=3)
cost <- rnorm(length(group), 100, 5)
current_score <- rnorm(length(group), 7, 2)
future_score <- current_score*runif(1)
dat <- data.frame(group, cost, current_score, future_score)
Run Code Online (Sandbox Code Playgroud)
以及给出总体加权组得分的函数:
wt_score <- function(group, dat)
{
one_group_dat <- dat[dat$group == group, ]
wt_score <- sum(one_group_dat$cost * (one_group_dat$current_score - one_group_dat$future_score))/sum(one_group_dat$cost)
return(wt_score)
}
Run Code Online (Sandbox Code Playgroud)
有没有办法对上述函数进行矢量化,以便我不必使用如下所示的循环?问题在于,在实践中,一个函数应用于数万个组和数百万个数据点,因此循环非常慢。
# THIS IS TOO SLOW!
dat$wt_score <- 0
for(i in 1:nrow(dat))
{
dat$wt_score[i] <- wt_score(dat$group[i], dat)
}
Run Code Online (Sandbox Code Playgroud) 我有以下代码,它接受输入 anx并填充输出向量y,我想使用 OpenMPsimd指令对其进行向量化:
for (size_t qi = 0; qi < nq; ++qi){
const auto ii = face_indices[qi*3], jj = face_indices[qi*3+1], kk = face_indices[qi*3+2];
y[ii] += x[kk] * fpl[ii] * fq[qi] * fpr[kk] - x[jj] * fpl[ii] * fq[qi] * fpr[jj];
y[kk] += x[ii] * fpl[kk] * fq[qi] * fpr[ii] - x[jj] * fpl[kk] * fq[qi] * fpr[jj];
y[jj] -= x[ii] * fpl[jj] * fq[qi] * fpr[ii] + x[kk] * fpl[jj] * fq[qi] * fpr[kk]; …Run Code Online (Sandbox Code Playgroud) 我试图做一个逻辑向量来检查一个元素是否等于上一个元素。
vector <- c(1, 1, 2, 2, 2, 3, 3)
Run Code Online (Sandbox Code Playgroud)
我想检查每个元素是否等于前一个元素,因此结果应为:
FALSE TRUE FALSE TRUE TRUE FALSE TRUE
Run Code Online (Sandbox Code Playgroud)
我知道我可以进行循环,但是效率不高(我有1600万行df)。所以
这不是理想的,但我可以管理的是:
for(i in 2:length(vector)) {print(vector[i] == vector[i-1])}
Run Code Online (Sandbox Code Playgroud)
那将永远。有矢量化的方法吗?
为什么这个函数返回浮点数?
func = lambda x: 1.
x = np.linspace(0,1,10)
func(x).shape
Run Code Online (Sandbox Code Playgroud)
结果是
func = lambda x: 1.
x = np.linspace(0,1,10)
func(x).shape
Run Code Online (Sandbox Code Playgroud)
我期望以下行为:
func = lambda x: 1. + 0*x
x = np.linspace(0,1,10)
func(x)
Run Code Online (Sandbox Code Playgroud)
array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])
Run Code Online (Sandbox Code Playgroud)
如何在不干扰 lambda 函数的情况下获得预期结果(即无需编写func = lambda x: 1. + 0*x)?
背后的想法是用户将此函数传递给另一个函数以在网格上进一步评估。我不能指望用户将常量函数设置为1 + 0*x。我应该怎么办?
我想改进一个简单的matlab函数.有没有算术方法来实现这个功能?我认为这会表现得更好.
function img_output = cutchannels(img_input, min, max)
[r c l] = size(img_input);
img_output = double(img_input);
for i = 1:r
for j = 1:c
for k = 1:l
if(img_output(i:j:k)> max)
img_output(i:j:k) = max;
elseif(img_output(i:j:k) < min)
img_output(i:j:k) = min;
end
end
end
end
end
Run Code Online (Sandbox Code Playgroud) 因为循环似乎非常慢,所以我想知道下面显示的代码中的嵌套循环是否可以使用矢量化bsxfun,也许GPU也可以引入.
码
%// Paramaters
i = 1;
j = 3;
n1 = 1500;
n2 = 1500;
%// Pre-allocate for output
LInc(n1+n2,n1+n2)=0;
%// Nested Loops - I
for x = 1:n1
for y = 1:n1
num = ((n2 ^ 2) * (L1(i, i) + L2(j, j) + 1)) - (n2 * n * (L1(x,i) + L1(y,i)));
LInc(x, y) = L1(x, y) + (num/denom);
LInc(y, x) = LInc(x, y);
end
end
%// Nested Loops - II
for x = 1:n1 …Run Code Online (Sandbox Code Playgroud) 我想创建一个矩阵M与指标i,j使M(i,j)=i/j.我可以使用两个循环来做到这一点但是有没有办法在不使用for循环的情况下做到这一点?
f <- function(n){
s <- 0
for (i in 1:n){
s <- s + (i/2)
}
print(s)
}
Run Code Online (Sandbox Code Playgroud)
当然,棘手的部分是s递归地依赖于前一个循环.
[编辑]
谢谢您的回答.我只是试图使用R中的矢量化与循环相比来验证性能的增量.
具有n = 10亿以上函数采用287秒,同时兼具sum((1:n)/2)和 sum(seq_len(n)/2)返回我一个错误,该系统"不能分配大小7.5 GB的载体"
为了比较,Julia中的相同函数(n = 1000000000)需要38秒(0.87定义类型s),在C++中使用优化编译2.48秒/0.87,使用numba装饰器在Python 98秒/ 0.88中编译.
鉴于此问题,我被要求优化代码。我似乎找不到找到使它更快运行的方法。
nmax= 2000;
mmax= 2000;
for m=1:mmax
for n=1:nmax
A(n,m)= n+m;
end
end
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?