Юлия усекает внутреннее измерение массива массивов - PullRequest
3 голосов
/ 07 февраля 2020

Учитывая массив массивов

x = [[1, 2, 3, 4], [4, 5, 6, 7]],

, что является чистым и эффективным способом обрезать каждый из внутренних массивов так, что я получаю

[[1, 2], [4, 5]]?

Есть ли что-нибудь столь же простое, как x[:,1:2], как для многомерных массивов?

Ответы [ 2 ]

6 голосов
/ 07 февраля 2020

Вы можете вещать getindex:

julia> x = [[1, 2, 3, 4], [5, 6, 7, 8]];

julia> getindex.(x, (1:2,))
2-element Array{Array{Int64,1},1}:
 [1, 2]
 [5, 6]

Кажется, это немного быстрее, чем при использовании map:

julia> foo(xs) = getindex.(xs, (1:2,))
foo (generic function with 1 method)

julia> bar(xs) = map(x -> x[1:2], xs)
bar (generic function with 1 method)

julia> @btime foo($([rand(1000) for _ in 1:1000]));
  55.558 μs (1001 allocations: 101.69 KiB)

julia> @btime bar($([rand(1000) for _ in 1:1000]));
  58.841 μs (1002 allocations: 101.70 KiB)
3 голосов
/ 07 февраля 2020

Если вы согласны с изменением входных векторов, то это очень эффективный способ сделать это:

resize!.(x, 2)

Это мутирует x на месте, поэтому вам не нужно назначать переменная вывода.

Вы также можете использовать view. Это не изменяет входные данные, но и не выделяет новый вектор. Это быстрее, чем транслируемая getindex, но не так быстро, как resize!:

xv = view.(x, Ref(1:2))
...