Как & ldquo; транспонировать & rdquo; список векторов?

Чтобы ответить на этот вопрос, мы должны посмотреть, как индексирование многомерного массива работает в Numpy. Давайте сначала скажем, что у вас есть массив x из вашего вопроса. Буфер, назначенный x, будет содержать 16 восходящих целых чисел от 0 до 15. Если вы обращаетесь к одному элементу, скажем x[i,j], NumPy должен определить расположение памяти этого элемента относительно начала буфера. Это делается путем вычисления фактического значения i*x.shape[1]+j (и умножения на размер int для получения фактического смещения памяти).

Если вы извлекаете подмассив с помощью базовой нарезки, такой как y = x[0:2,0:2], результирующий объект будет совместно использовать базовый буфер с помощью x. Но что произойдет, если вы получите y[i,j]? NumPy не может использовать i*y.shape[1]+j для вычисления смещения в массиве, поскольку данные, принадлежащие y, не являются последовательными в памяти.

NumPy решает эту проблему, введя шаги . При вычислении смещения памяти для доступа к x[i,j] то, что на самом деле вычисляется, является i*x.strides[0]+j*x.strides[1] (и это уже включает в себя коэффициент для размера int):

x.strides
(16, 4)

Когда извлечено y как и выше, NumPy не создает новый буфер, но делает создание нового объекта массива, ссылающегося на тот же буфер (иначе y будет просто равен x.) Новый объект массива будет имеют другую форму, тогда x и, возможно, другое начальное смещение в буфере, но будут делиться шагами с x (в этом случае, по крайней мере):

y.shape
(2,2)
y.strides
(16, 4)

Таким образом, вычисляя смещение памяти для y[i,j] даст правильный результат.

Но что делать NumPy для чего-то вроде z=x[[1,3]]? Механизм шагов не позволит правильно проиндексировать, если исходный буфер используется для z. NumPy теоретически мог бы добавить еще более сложный механизм, чем шаги, но это сделало бы доступ к элементу относительно дорогостоящим, как-то игнорируя всю идею массива. Кроме того, представление больше не будет действительно легким объектом.

Это подробно описано в документации NumPy по индексированию .

О, и почти забыл о вашем фактическом вопросе: вот как сделать индексацию с несколькими списками работать как ожидалось:

x[[[1],[3]],[1,3]]

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

x[1::2, 1::2]

3
задан gaazkam 3 March 2019 в 15:45
поделиться

5 ответов

transposedAsdf = as.list(as.data.frame(t(as.data.frame(asdf))))
transposedAsdf
$V1
[1]  1 10

$V2
[1]  2 20

$V3
[1]  3 30

$V4
[1]  4 40

$V5
[1]  5 50
0
ответ дан G5W 3 March 2019 в 15:45
поделиться

Вот один из способов:

split(do.call(cbind, asdf), 1:length(asdf[[1]]))
# 

Вот один из способов:

1` # [1] 1 10 # #

Вот один из способов:

2` # [1] 2 20 # #

Вот один из способов:

3` # [1] 3 30 # #

Вот один из способов:

4` # [1] 4 40 # #

Вот один из способов:

5` # [1] 5 50
0
ответ дан Gregor 3 March 2019 в 15:45
поделиться

Опция с использованием data.table

data.table::transpose(asdf)
#[[1]]
#[1]  1 10

#[[2]]
#[1]  2 20

#[[3]]
#[1]  3 30

#[[4]]
#[1]  4 40

#[[5]]
#[1]  5 50 
0
ответ дан markus 3 March 2019 в 15:45
поделиться

Решение с использованием пакета purrr.

library(purrr)

asdf2 <- transpose(asdf) %>% map(unlist)
asdf2
# [[1]]
# [1]  1 10
# 
# [[2]]
# [1]  2 20
# 
# [[3]]
# [1]  3 30
# 
# [[4]]
# [1]  4 40
# 
# [[5]]
# [1]  5 50
0
ответ дан www 3 March 2019 в 15:45
поделиться

Один вариант с Map из base R

do.call(Map, c(f = c, asdf))
0
ответ дан akrun 3 March 2019 в 15:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: