Сбор элементов массива в Julia

#arrays #collections #julia

#массивы #Коллекции #julia

Вопрос:

Я хочу понять, как иметь возможность собирать элементы из n по m размерному массиву и сохранять их в n векторах m измерений. Например, у меня есть следующий массив размером 3 x 2, и я хочу сохранить пару каждой строки в вектор.

 Array1 = [ 1 0; 2 0; 3 0]
 

Это дает:

 3×2 Array{Int64,2}:
1  0
2  0
3  0
 

Идея состоит в том, чтобы создать цикл for, который на каждой итерации сохраняет в 2-мерный вектор значения массива выше.

Я не уверен, как это сделать, поскольку collect функция будет сохранять только элементы одного и того же столбца из моих экспериментов до сих пор.

Как я могу сохранить каждую пару в вектор тогда?

Комментарии:

1. поможет eachrow ли или eachcol поможет здесь?

2. Мне нужно было бы найти документацию, чтобы посмотреть, может ли она помочь (никогда не использовал их раньше).

3. Это могло бы помочь, но как мне каждый раз определять / сохранять новый вектор?

Ответ №1:

Это может быть так просто, как collect(eachrow(Array1))

 julia> collect(eachrow(Array1))
3-element Vector{SubArray{Int64, 1, Matrix{Int64}, Tuple{Int64, Base.Slice{Base.OneTo{Int64}}}, true}}:
 [1, 0]
 [2, 0]
 [3, 0]
 

Это короткое и, что более важно, стабильное по типу, поэтому оно более производительно, чем Any[] решение. Но это создает view основу Matrix , которая иногда не является тем, что вы хотите, особенно принимая во внимание, что Julia ориентирована на столбцы, поэтому просмотр строк будет относительно медленным. Если это так, вы можете пойти с

 julia> collect.(eachrow(Array1))
3-element Vector{Vector{Int64}}:
 [1, 0]
 [2, 0]
 [3, 0]
 

что по-прежнему происходит очень быстро.

Но вы также можете подумать о том, как вы используете эту конструкцию. Если, например, все, что вы хотите, это перебирать строки, то собирать вообще не нужно, вы можете использовать eachrow прямолинейно, без промежуточной материализации.

Ответ №2:

Хорошо, я нашел удовлетворительный ответ, который я опубликую здесь для дальнейшего использования.

Сначала я определяю список векторов, которые могут принимать любые значения:

 listV = Any[];
 

Затем я создаю for цикл, в котором хранится каждая пара элементов массива Array , используя eachrow :

 for row in eachrow(Array);
    push!(listV, row);
end
 

Этого достаточно.

Комментарии:

1. В итоге я использовал что-то вроде Array{Float64}(undef, 1, 2);

2. Я удалил свой комментарий над вашим @Marion, потому что он был неправильным. Но Array{Float64}(undef, 1, 2) это тоже не имеет смысла. Вы могли бы использовать Vector{Vector{eltype(Array1)}}(undef, size(Array1, 1)) . Но вы действительно должны использовать решение @AndrejOskin, оно определенно самое идиоматичное и элегантное.