2
votes

Quelle est la bonne façon de sélectionner des lignes dans une matrice par un tableau booléen?

J'ai un tableau booléen (à partir des calculs précédents) et je voudrais sélectionner les lignes associées à partir de plusieurs matrices. C'est pourquoi j'ai besoin du tableau d'index approprié (à réutiliser plus tard). C'est facile en Matlab et en python mais je n'utilise pas la bonne manière julienne de le faire ...

Je connais DataFrames, mais j'aimerais trouver une matrice orthodoxe et un tableau pour faire cela.

Dans Matlab, je dirais:

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

Voici ce que j'ai réussi à faire:

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

Ce que j'ai supposé, c'est qu'il existe un moyen plus court d'exprimer la phrase ci-dessus. dans la version 0.6, il y avait la fonction find (), mais je n'ai pas encore compris la documentation de Julia (je suis très très novice dans ce domaine).


0 commentaires

3 Réponses :


1
votes

find dans 0.6 a été renommé en findall dans Julia 1.0.

Pour obtenir inds , vous pouvez simplement faire ce qui suit:

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

Vous n'avez pas besoin de calculer d'abord le someTest intermédiaire, qui allouerait un tableau que vous n'avez pas l'intention d'utiliser. Au lieu de cela, vous pouvez faire le test avec findall en passant directement une fonction de prédicat.

inds = findall(someTest)

Cela renverra les indices de données pour lequel le prédicat rem (x, 2) == 0 renvoie vrai. Cela n'allouera pas de tableau intermédiaire pour trouver les indices, et devrait être plus rapide.

En remarque, la plupart du temps, vous n'avez pas besoin de matérialiser une plage dans Julia. Les plages sont déjà itérables et indexables. Ils seront automatiquement convertis en Array en cas de besoin. Array (1: n) ou collect (1: n) sont généralement redondants et alloue plus de mémoire.

p >


0 commentaires

2
votes

Vous pouvez utiliser le BitArray pour sélectionner directement les éléments:

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

Pour votre cas:

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


0 commentaires

0
votes

Votre code Matlab ne fonctionne pas. A est juste un vecteur de ligne (matrice 1x9), donc lorsque vous essayez de faire A (inds, :) , vous obtenez une erreur:

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


0 commentaires