уменьшить одно измерение внутри ndarray - PullRequest
0 голосов
/ 25 мая 2018

У меня есть координаты точек, хранящиеся в 3-мерном массиве:
(UPD. На самом деле массив numpy -приведен ndarray, извините за путаницу в начальной версии)

a = [ [[11,12]], [[21,22]], [[31,32]], [[41,42]] ]

вы видите, что каждая пара координат хранится как вложенный двумерный массив, такой как [[11,12]], хотя я бы хотел, чтобы он был [11,12], т.е. мой массив должен иметь следующее содержимое:

b = [ [11,12], [21,22], [31,32], [41,42] ]

Таккак перейти с a на b форму?Сейчас мое решение состоит в том, чтобы создать список и затем преобразовать его в массив с numpy:

b = numpy.array([p[0] for p in a])

Это работает, но я предполагаю, что должен быть более простой и понятный способ ...

UPD.Первоначально я пытался сделать простое понимание: b = [p[0] for p in a] - но затем b оказался списком, а не массивом - я предполагаю, что это потому, что исходный массив a равен ndarray из numpy

Ответы [ 4 ]

0 голосов
/ 25 мая 2018

Если вы собираетесь использовать numpy позже, тогда лучше избегать понимания списка.Также всегда полезно максимально автоматизировать процесс, поэтому вместо ручного выбора одноэлементного измерения просто позвольте numpy позаботиться о: b=numpy.array(a).squeeze() Если нет других одноэлементных измерений, которые вам необходимо сохранить.

0 голосов
/ 25 мая 2018

Если вы делаете хотите использовать numpy:

b = np.array(a)[:, 0, :]

Это будет быстрее, чем понимание.


Ну ... я, конечно, подумалбыло бы

a = np.random.random((100_000, 1, 2)).tolist()

%timeit np.array([x[0] for x in a])
41.1 ms ± 304 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

%timeit np.array(a)[:, 0, :]
57.6 ms ± 1.27 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

%timeit x = np.array(a); x.shape = len(a), 2
58.2 ms ± 381 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

edit

О, если это массив numpy, то определенно используйте этот метод.Или используйте .squeeze(), если вы уверены, что он не пустой.

0 голосов
/ 25 мая 2018

Чтобы выровнять «вложенный двумерный массив, подобный», как вы их называете, вам просто нужно получить первый элемент.arr[0]

Примените эту концепцию несколькими способами:

  • понимание списка (наиболее эффективный): flatter_a_compr = [e[0] for e in a]
  • итерация (второй лучший результат):

    b =[]
    for e in a:
        b.append(e[0])
    
  • лямбда (непифоническая): flatter_a = list(map(lambda e : e[0], a))

  • numpy (худшая производительность): flatter_a_numpy = np.array(a)[:, 0, :]
0 голосов
/ 25 мая 2018

Вот еще одно решение, использующее понимание списка:

b = [x[0] for x in a]
...