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

时间:2019-04-22 08:44:16

标签: julia

我有一个布尔数组(根据以前的计算),我想从几个矩阵中选择相关的行。这就是为什么我需要适当的索引数组(以后再使用)的原因。在Matlab和python中,这很容易,但是我没有掌握正确的朱利安方式...

我知道DataFrames,但是想找到一个正统的矩阵和数组方式来做到这一点。

在Matlab中,我会说:

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)!

我的工作是这样的:

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,:];

我假设有一种表达上述短语的较短方法。在v。0.6中,有find()函数,但是我对julia文档还没有很好的了解(我是一个非常新手)。

3 个答案:

答案 0 :(得分:2)

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

julia> A[someTest]
5-element Array{Float64,1}:
  3.0
  5.0
  7.0
  9.0
 11.0

适合您的情况:

julia> A[someTest,:] == A[inds,:]
true

答案 1 :(得分:1)

find在0.6中被重命名为findall在Julia 1.0中。

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

inds = findall(someTest)

您不必先计算中间变量someTest,该中间变量将分配您不打算使用的数组。相反,您可以使用findall直接通过谓词函数来进行测试。

inds = findall(x -> rem(x,2) == 0, data)

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

请注意,大多数情况下,您不需要在Julia中实现范围。范围已经是可迭代和可索引的。如有需要,它们会自动转换为ArrayArray(1:n)collect(1:n)通常是多余的,并且分配更多的内存。

答案 2 :(得分:0)

您的Matlab代码不起作用。 A只是行向量(1x9矩阵),因此当您尝试执行A(inds, :)时会出现错误:

>> Anew= A(inds,:)
Index in position 1 exceeds array bounds
(must not exceed 1).

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

Matlab(我确定这次是矩阵):

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

现在,朱莉娅:

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所说。