首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用布尔数组从矩阵中选择行的正确方法是什么?

用布尔数组从矩阵中选择行的正确方法是什么?
EN

Stack Overflow用户
提问于 2019-04-22 16:44:16
回答 3查看 262关注 0票数 2

我有一个布尔数组(来自以前的计算),我想从几个矩阵中选择相关的行。这就是为什么我需要正确的索引数组(稍后重用)的原因。这在Matlab和python中很容易,但我并不认为正确的julian方法是正确的。

我知道DataFrames,但我希望找到一种标准的矩阵和数组方法来实现这一点。

在Matlab中,我会说:

代码语言:javascript
运行
复制
n= 9; temp= 1:n; A= 1.0 + temp;
someTest= mod(temp,2) == 0; % just a substitute of a more complex case

% now I have both someTest and A!
inds= find(someTest); Anew= A(inds,:); 
% I got inds (which I need)!

我得到的结果是:

代码语言:javascript
运行
复制
n= 10; data= Array(1:n); A= 1.0 .+ data;
someTest= rem.(data,2) .== 0;

inds= [xy[2] for xy in zip(someTest,1:length(someTest)) if xy[1]]; # (*)
Anew= A[inds,:];

我假设有一些更短的方式来表达上面的短语。在v0.6中有find()函数,但是我还没有很好地理解julia文档(在这方面我是一个非常非常新手)。

EN

回答 3

Stack Overflow用户

发布于 2019-04-22 17:04:25

您可以直接使用BitArray来选择元素:

代码语言:javascript
运行
复制
julia> A[someTest]
5-element Array{Float64,1}:
  3.0
  5.0
  7.0
  9.0
 11.0

对于你的案例:

代码语言:javascript
运行
复制
julia> A[someTest,:] == A[inds,:]
true
票数 2
EN

Stack Overflow用户

发布于 2019-04-22 16:58:49

在Julia1.0中,find在0.6中被重命名为findall

要获取inds,只需执行以下操作:

代码语言:javascript
运行
复制
inds = findall(someTest)

您不必首先计算中间someTest,这将分配一个您不打算使用的数组。相反,您可以使用findall直接传递一个谓词函数来进行测试。

代码语言:javascript
运行
复制
inds = findall(x -> rem(x,2) == 0, data)

这将返回谓词rem(x,2) == 0返回true的data的索引。这将不会分配一个中间数组来查找索引,而且应该更快。

顺便说一句,大多数情况下,你不需要在Julia中实现一个范围。范围已经是可迭代和可索引的。它们会在需要时自动转换为ArrayArray(1:n)collect(1:n)通常是冗余的,并且分配更多的内存。

票数 1
EN

Stack Overflow用户

发布于 2019-04-23 18:38:41

你的Matlab代码不能工作。A只是一个行向量(1x9矩阵),所以当您尝试执行A(inds, :)时,您会得到一个错误:

代码语言:javascript
运行
复制
>> Anew= A(inds,:)
Index in position 1 exceeds array bounds
(must not exceed 1).

但是如果你只是解决这个问题,你可以在Matlab和Julia中以完全相同的方式解决这个问题,使用逻辑索引或常规索引:

Matlab (这次我要确保它是一个矩阵):

代码语言:javascript
运行
复制
n = 9;
temp = (1:n).'; 
A = temp * (1:4);
inds = mod(temp,2) == 0;

>> A(inds, :) % using logical indices

ans =

     2     4     6     8
     4     8    12    16
     6    12    18    24
     8    16    24    32

>> A(find(inds), :) % using regular indices

ans =

     2     4     6     8
     4     8    12    16
     6    12    18    24
     8    16    24    32

现在,朱莉娅:

代码语言:javascript
运行
复制
n = 9;
temp = 1:n;
A = temp .* (1:4)'; # notice that we're transposing the opposite vector from Matlab
inds = mod.(temp, 2) .== 0;  # you can use iseven.(temp) instead

julia> A[inds, :]  # logical indices (BitArray)
4×4 Array{Int64,2}:
 2   4   6   8
 4   8  12  16
 6  12  18  24
 8  16  24  32

julia> A[findall(inds), :]  # regular integer indices
4×4 Array{Int64,2}:
 2   4   6   8
 4   8  12  16
 6  12  18  24
 8  16  24  32

在本例中,我将使用Julia和Matlab中的逻辑索引。事实上,Matlab linter (在编辑器中)会告诉你应该在这里使用逻辑索引,因为它更快。然而,在Julia中,可能存在使用inds = findall(iseven, temp)更有效的情况,只需跳过逻辑BitArray,就像@hckr所说的那样。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55791605

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档