Объединение и разделение массивов
На предыдущем занятии мы познакомились со способами изменения форм массивов. Здесь мы узнаем как реализуются операции объединения и разделения массивов. Для этой задачи в NumPy реализованы специальные функции, которые мы сейчас и рассмотрим.
Функции hstack и vstack
Предположим у нас есть два двумерных массива:
a = np.array([(1, 2), (3, 4)]) b = np.array([(5, 6), (7, 8)])

Их можно объединить как по горизонтали, так и по вертикали, с помощью функций:
np.hstack([a, b]) # объединение по оси axis1 (размерность 2x4) np.vstack([a, b]) # объединение по оси axis0 (размерность 4x2)
Примеры работы этих двух функций представлены на рисунке ниже:

Эти же операции можно выполнять и с многомерными массивами. Например, определим два трехмерных массива:
a = np.fromiter(range(18), dtype='int32') b = np.fromiter(range(18, 36), dtype='int32') a.resize(3, 3, 2) b.resize(3, 3, 2)
И выполним функции:
c = np.hstack([a, b]) # размерность 3x6x2 d = np.vstack([a, b]) # размерность 6x3x2
Как видите, здесь произошло формальное объединение по оси axis1 в функции hstack и по оси axis0 в функции vstack.
Разумеется, чтобы эти функции работали, размерность массивов по объединяемым осям должны совпадать.
Аналогичным образом происходит объединение и одномерных массивов:
a = np.fromstring('1 2 3 4', sep = ' ') b = np.fromstring('5 6 7 8', sep = ' ')
И при выполнении:
np.hstack([a, b])
array([1., 2., 3., 4., 5., 6., 7., 8.])
А во втором случае:
np.vstack([a, b])
результатом будет двумерный массив:
Функции column_stack и row_stack
Давайте теперь зададимся вопросом: как объединить наши два одномерных массива столбцами? Чтобы результат выглядел вот так:

Для этого хорошо подходит функция column_stack():
np.column_stack([a, b]) # формирование массива 4x2
Если с ее помощью объединять двумерные и многомерные массивы, то она будет давать тот же результат, что и функция hstack().
Другая аналогичная функция row_stack(), в принципе, делает то же самое, что и функция vstack() заметных отличий здесь нет. Ее можно использовать так:
np.row_stack([a, b]) # матрица 2x4
Функция concatenate
Для объединения массивов вдоль строго определенной оси можно воспользоваться функцией concatenate(). Например, возьмем два трехмерных массива:
a = np.arange(1, 13) b = np.arange(13, 26) a.resize(3, 3, 2) b.resize(3, 3, 2)
И объединим их по каждой из осей:
c0 = np.concatenate([a, b], axis=0) # размерность 6x3x2 c1 = np.concatenate([a, b], axis=1) # размерность 3x6x2 c2 = np.concatenate([a, b], axis=2) # размерность 3x3x4
Объекты r_ и c_
Еще один способ объединения и создания массивов – это использование специальных объектов r_ и c_. Например, объект r_ создает копии массивов, следующими способами:
np.r_[ [1, 2, 3], 4, 5] # список + дополнительные элементы np.r_[ 1:9, 90, 100] # срез + два элемента np.r_[ np.array([1,2,3]), np.array([4,5,6])] # объединение двух массивов np.r_[ [(1,2,3), (4,5,6)], [(7,8,9)] ] # объединение двумерного и одномерного списков
По аналогии работает и второй объект c_, только объединение выполняется по второй оси axis1:
np.c_[1:5] np.c_[ [1, 2, 3], [4, 5, 6]] np.c_[ [(1,2,3), (4,5,6)], [[7],[8]] ]
Разделение массивов
Массивы в NumPy можно не только объединять, но и разделять. Для этого существуют специальные функции hsplit и vsplit. Рассмотрим их работу на простых примерах. Пусть имеется одномерный массив из 10 элементов:
a = np.arange(10)
И мы хотим разделить его на две равные части. Это реализуется с помощью функции hsplit:
np.hsplit(a, 2)
которая возвращает список из двух массивов. Второй параметр 2 указывает число частей, на которые делится исходный массив. Причем, деление выполняется по горизонтали. Если в нашем примере указать 3 части, то возникнет ошибка:
np.hsplit(a, 3) # ошибка 10 на 3 нацело не делится
так как 10 элементов нельзя равномерно разбить на 3 части.
Также ошибка будет и при разбиении этого массива по вертикали:
np.vsplit(a, 2) # ошибка: нет вертикальной оси
так как массив имеет одну горизонтальную ось. Чтобы вторая функция сработала, преобразуем массив a в вектор столбец:
a.shape = 10, -1 # вектор-столбец
а, затем, разобьем по вертикали:
np.vsplit(a, 2)
На выходе получим два одномерных массива длиной 5 элементов.
Эти же функции можно использовать и с многомерными массивами, например, так:
a = np.arange(12) a.resize(2, 6) # двумерный массив 2x6 np.hsplit(a, 2) # разбиение по горизонтали np.vsplit(a, 2) # разбиение по вертикали
Функция array_split
Рассмотренные функции выполняют разбиение или по первой оси axis0 или по второй оси axis1. Но что если нам нужно выполнить разбиение по произвольной оси многомерного массива? Для этого существует функция array_split(). Ее работа аналогична рассмотренным выше функциям, только дополнительно указывается ось разбиения. Например:
a = np.arange(18) a.resize(3, 3, 2) np.array_split(a, 2, axis=2) np.array_split(a, 3, axis=0) np.array_split(a, 3, axis=1)
Видео по теме

#1. Пакет numpy — установка и первое знакомство | NumPy уроки

#2. Основные типы данных. Создание массивов функцией array() | NumPy уроки

#3. Функции автозаполнения, создания матриц и числовых диапазонов | NumPy уроки

#4. Свойства и представления массивов, создание их копий | NumPy уроки

#5. Изменение формы массивов, добавление и удаление осей | NumPy уроки

#6. Объединение и разделение массивов | NumPy уроки

#7. Индексация, срезы, итерирование массивов | NumPy уроки

#8. Базовые математические операции над массивами | NumPy уроки

#9. Булевы операции и функции, значения inf и nan | NumPy уроки

#10. Базовые математические функции | NumPy уроки

#11. Произведение матриц и векторов, элементы линейной алгебры | NumPy уроки

#12. Множества (unique) и операции над ними | NumPy уроки

#13. Транслирование массивов | NumPy уроки
© 2024 Частичное или полное копирование информации с данного сайта для распространения на других ресурсах, в том числе и бумажных, строго запрещено. Все тексты и изображения являются собственностью сайта
Как разбить массив на подмассивы используя «0» как разделитель?

Если есть ещё какие-нибудь интересные решения, можете приложить в комментарии к ответу.
Ответ написан более года назад
Комментировать
Нравится 1 Комментировать

Сергей П @trapwalker Куратор тега Python
Программист, энтузиаст
Без сторонних либ я бы делал так:
def split0(arr: list) -> list: res = [[]] for x in arr: res[-1].append(x) if x else res.append([]) return res
А вот для любителей функциональщины:
from itertools import takewhile def split0(a): it = iter(a) return [[x for x in takewhile(bool, it)] for _ in range(a.count(0) + 1)]
Ответ написан более года назад
Нравится 1 2 комментария

В последнем решении есть небольшая опечатка, вот исправленный вариант:
from itertools import takewhile def split0(a): it = iter(a) return [[x for x in takewhile(bool, it)] for _ in range(a.count(0) + 1)]

Сергей П @trapwalker Куратор тега Python
Как одним выражением разбить массив на группы из n элементов в python?
У меня есть массив с неизвестным количеством элементов и я хочу получить из него массив массивов из 5 элементов, а остаток от деления на 5 убрать. Например:
[n0, n1, n2 . n17] -> [[n0, n1, n2, n3, n4], [n5-n9], [n10-n14]]
[n0, n1, n2, n3] -> []
Как это сделать при помощи одного выражения?
- Вопрос задан более трёх лет назад
- 14123 просмотра
Комментировать
Решения вопроса 2
software engineer
>>> items, chunk = range(1,20), 3 >>> zip(*[iter(items)]*chunk) [(1, 2, 3), (4, 5, 6), (7, 8, 9), (10, 11, 12), (13, 14, 15), (16, 17, 18)]
Ответ написан более трёх лет назад
Комментировать
Нравится 5 Комментировать
Ху Нью @stopbreath
начинающий/практикующий python-программист
In [9]: s = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] In [10]: [s[d:d+5] for d in xrange(0, len(s), 5)] Out[10]: [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14]]
Примерно так?
Ответ написан более трёх лет назад
Нравится 3 1 комментарий
Boldy @Boldy Автор вопроса
[s[d:d+5] for d in xrange(0, len(s), 5) if len(s[d:d+5]) == 5] (чтобы отбросить остаток)
Спасибо. То, что я искал.
Ответы на вопрос 0
Ваш ответ на вопрос
Войдите, чтобы написать ответ

- Python
- +1 ещё
Что делать если не работают клавиатуры в aiogram?
- 1 подписчик
- 16 минут назад
- 17 просмотров
Как разбить массив на подмассивы python
Массив $$$b$$$ называется подмассивом массива $$$a$$$, если он образует непрерывный подотрезок $$$a$$$, то есть равен $$$a_l$$$, $$$a_$$$, $$$\ldots$$$, $$$a_r$$$ для некоторых $$$l, r$$$.
Пусть $$$m$$$ — некоторая зафиксированная константа. Для любого массива, содержащего хотя бы $$$m$$$ элементов, определим его симпатичность , как сумму $$$m$$$ наибольших элементов этого массива. Например:
- Если массив $$$x = [4, 3, 1, 5, 2]$$$ и $$$m = 3$$$, то $$$3$$$ наибольших элемента $$$x$$$ равны $$$5$$$, $$$4$$$ и $$$3$$$, тем самым симпатичность $$$x$$$ равна $$$5 + 4 + 3 = 12$$$.
- Если массив $$$x = [10, 10, 10]$$$ и $$$m = 2$$$, то симпатичность $$$x$$$ равна $$$10 + 10 = 20$$$.
Вам дан массив $$$a_1, a_2, \ldots, a_n$$$, значение константы $$$m$$$ и целое число $$$k$$$. Вам нужно разбить массив $$$a$$$ на ровно $$$k$$$ подмассивов таких, что:
- Каждый элемент $$$a$$$ принадлежит ровно одному подмассиву.
- Каждый подмассив содержит хотя бы $$$m$$$ элементов.
- Суммарная симпатичность всех $$$k$$$ подмассивов в разбиении является наибольшей возможной.
Входные данные
Первая строка содержит три целых числа $$$n$$$, $$$m$$$ и $$$k$$$ ($$$2 \le n \le 2 \cdot 10^5$$$, $$$1 \le m$$$, $$$2 \le k$$$, $$$m \cdot k \le n$$$) — количество элементов в $$$a$$$, константа $$$m$$$ в условии и количество подмассивов, на которые нужно разбить.
Вторая строка содержит $$$n$$$ целых чисел $$$a_1, a_2, \ldots, a_n$$$ ($$$-10^9 \le a_i \le 10^9$$$).
Выходные данные
В первой строке выведите наибольшую возможную сумму симпатичностей подмассивов в разбиении.
- В первый подмассив попадают элементы с индексами от $$$1$$$ до $$$p_1$$$.
- Во второй подмассив попадают элементы с индексами от $$$p_1 + 1$$$ до $$$p_2$$$.
- $$$\ldots$$$.
- Все элементы с индексами от $$$p_ + 1$$$ до $$$n$$$ попадают в последний, $$$k$$$-й подмассив.
В случае если есть несколько оптимальных разбиений, выведите любое из них.
Входные данные
9 2 3 5 2 5 2 4 1 1 3 2