Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Переформатирование и слияние Python: Numpy-массивы

Numpy

Объединение данных в единую структуру — это операция, с которой сталкиваются при поступлении данных. С помощью нее мы можем объединять данные из разных источников, а также асинхронные ответы сервера и результаты параллельных и последовательных вычислений. В стандартном Python есть структуры данных list и set. Их можно объединять с помощью append() и update(). Еще можно использовать функцию zip() — она нужна для попарного объединения значений. В Numpy это работает по-другому.

Массивы numpy.ndarray поддерживают сценарии объединения массивов различной размерности по разным осям индексов. Для этого используются четыре метода:

  • Конкатенация — concatenate()
  • Объединение массивов по горизонтали — hstack()
  • Объединение массивов по вертикали — vstack()
  • Попарное объединение элементов списков — column_stack()

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

Одномерные структуры данных

Начнем с одномерных структур данных, потому что они встречаются чаще всего.

Объединение списков значений в Python делаются операцией +. В Numpy ту же роль выполняют методы concatenate() и hstack():

import numpy as np

arr1 = np.array([0, 1, 2, 3,])
arr2 = np.array([4, 5, 6, 7])

print(np.concatenate([arr1, arr2]))
# => [0 1 2 3 4 5 6 7]
print(np.hstack([arr1, arr2]))
# => [0 1 2 3 4 5 6 7]
print([0, 1, 2, 3,] + [4, 5, 6, 7])
# => [0, 1, 2, 3, 4, 5, 6, 7]

Обратите внимание, что в примере выше мы объединили массивы по горизонтали. Для этого мы использовали метод hstack() (сокращение от английского horisontal stack).

А теперь попробуем объединить массивы в вертикальном направлении. Здесь понадобится метод vstack() (от англ. vertical stack). Для вертикального объединения также подойдет инициализация нового массива из списка исходных массивов. Этот подход аналогичен формированию списка списков:

print(np.vstack([arr1, arr2]))
# => [[0 1 2 3]
#  [4 5 6 7]]
print(np.array([arr1, arr2]))
# => [[0 1 2 3]
#  [4 5 6 7]]
print([[0, 1, 2, 3,], [4, 5, 6, 7]])
# => [[0, 1, 2, 3], [4, 5, 6, 7]]

Еще одна удобная и распространенная операция — попарное объединение элементов списков. Как уже говорили, в стандартном Python для этой цели используется метод zip().

В Numpy используется аналог — метод column_stack():

print(list(zip([0, 1, 2, 3,], [4, 5, 6, 7])))
# => [(0, 4), (1, 5), (2, 6), (3, 7)]
print(np.column_stack([arr1, arr2]))
# => [[0 4]
#  [1 5]
#  [2 6]
#  [3 7]]

В итоге мы рассмотрели все четыре метода и выяснили, как они работают для одномерных массивов. Эти же знания применимы и к массивам с большей размерностью.

Двумерные структуры данных

Попробуем объединить двумерные структуры — матрицы. Это можно сделать в двух направлениях.

В этом примере мы объединим данные по вертикали:

arr1 = np.array([[5, 8], [8, 9]])
arr2 = np.array([[3, 1], [7, 2]])

print(np.concatenate([arr1, arr2]))
# => [[5 8]
#  [8 9]
#  [3 1]
#  [7 2]]
print(np.vstack([arr1, arr2]))
# => [[5 8]
#  [8 9]
#  [3 1]
#  [7 2]]

Также можно объединять данные по горизонтали:

print(np.concatenate([arr1, arr2], axis = 1))
# => [[5 8 3 1]
#  [8 9 7 2]]
print(np.hstack((arr1, arr2)))
# => [[5 8 3 1]
#  [8 9 7 2]]

Все примеры выше демонстрировали объединение двух массивов. Однако массивов может быть больше.

Многомерные структуры данных

Предположим, что в результате асинхронных запросов к серверу было получено три списка значений для трех дней продаж магазина. Чтобы объединить ответы сервера в единую таблицу, можно использовать все те же методы:

response_values_day1 = np.array([7, 1, 7, 8])
response_values_day2 = np.array([4, 2, 4, 5])
response_values_day3 = np.array([3, 5, 2, 3])

orders = np.vstack([
    response_values_day1,
    response_values_day2,
    response_values_day3,
])
print(orders)
# => [[7 1 7 8]
#  [4 2 4 5]
#  [3 5 2 3]]

Запросы к серверу могут быть не по дням, а по магазинам. В этом случае также применимы методы объединения:

response_values_shop1 = np.array([ 7, 4, 3,])
response_values_shop2 = np.array([ 1, 2, 5,])
response_values_shop3 = np.array([ 7, 4, 2,])
response_values_shop4 = np.array([ 8, 5, 3,])

orders = np.vstack([
    response_values_shop1,
    response_values_shop2,
    response_values_shop3,
    response_values_shop4,
])
print(orders.T)
# => [[7 1 7 8]
#  [4 2 4 5]
#  [3 5 2 3]]

В примере выше используется транспонирование матрицы. Результат транспонирования — это матрица, в которой столбцы исходной таблицы становятся строками.

Посмотрим на исходную матрицу:

print(orders)
# => [[7 4 3]
#  [1 2 5]
#  [7 4 2]
#  [8 5 3]]

А теперь сравним ее с транспонированной:

print(orders.T)
# => [[7 1 7 8]
#  [4 2 4 5]
#  [3 5 2 3]]

Выводы

В этом уроке мы рассмотрели методы объединения массивов numpy.ndarray. Все методы работают для данных с разной размерностью: одномерными, двумерными и многомерными. При этом на вход методы могут получать любое количество массивов.

Чтобы выбрать правильный метод объединения, проговорите про себя, что нужно сделать:

  • Если горизонтально состыковать массивы, используем hstack()
  • Если вертикально состыковать массивы, используем vstack()
  • Если объединить значений поэлементно из нескольких колонок, используем column_stack()

Самостоятельная работа

Нажмите, чтобы увидеть тестовые данные
word_array = ['мыла', 'мама', 'мама', 'раму', 'мыла', 'мама']

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

  • Полносвязные нейронные сети используют векторы

  • Рекуррентные и сверточные нейронные сети делают преобразование над матрицами

Попробуем подготовить текстовые данные для обоих подходов глубокого обучения:

Шаг 1. Поработаем с одномерными представлениями. Вспомним кодировку текста в числовые данные:

   мама = (0,2,1)
   мыла = (1,3,0)
   раму = (1,1,2)
   мама мыла раму =['мама','мыла','раму'] = [0,2,1,1,3,0,1,1,2]

Напишите функцию word2vec(), которая получает на вход список слов и кодирует их в список чисел. Постарайтесь использовать методы объединения массивов numpy.ndarray.

Нажмите, чтобы увидеть ответ
    def test(code_array: np.array):
        expected_code_array = np.array([1, 3, 0, 0, 2, 1, 0, 2, 1, 1, 1, 2, 1, 3, 0, 0, 2, 1])
        # shape
        assert code_array.shape == expected_code_array.shape
        # type
        assert np.array_equal(code_array, expected_code_array)

    def word2vec(word_array):
        code_rules = {
            'мама' : (0,2,1),
            'мыла' : (1,3,0),
            'раму' : (1,1,2)
        }
        return np.hstack([np.array(code_rules[one_word]) for one_word in word_array])

    code_array = word2vec(word_array)
    test(code_array)

Шаг 2. Сделаем преобразование для двумерных представлений:

   мама = (0,2,1)
   мыла = (1,3,0)
   раму = (1,1,2)
   мама мыла раму = ['мама', 'мыла', 'раму'] = [[0,2,1],[1,3,0],[1,1,2]]

Это и есть матричное представление текста, в котором векторные представления слов расположены по строкам по порядку сверху вниз. Напишите функцию word2matrix(), которая получает на вход список слов и кодирует их в матричное представление (массив numpy.ndarray). Постарайтесь использовать методы объединения массивов numpy.ndarray.

Нажмите, чтобы увидеть ответ
    def test(code_array: np.array):
        expected_code_array = np.array([
            [1, 3, 0],
            [0, 2, 1],
            [0, 2, 1],
            [1, 1, 2],
            [1, 3, 0],
            [0, 2, 1]]
        )
        # shape
        assert code_array.shape == expected_code_array.shape
        # type
        assert np.array_equal(code_array, expected_code_array)

    def word2matrix(word_array):
        code_rules = {
            'мама' : (0,2,1),
            'мыла' : (1,3,0),
            'раму' : (1,1,2)
        }
        return np.vstack([np.array(code_rules[one_word]) for one_word in word_array])
    code_array = word2matrix(word_array)
    test(code_array)

Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты

Об обучении на Хекслете

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
1000
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы
профессия
от 5 025 ₽ в месяц
новый
Сбор, анализ и интерпретация данных
9 месяцев
с нуля
Старт 25 апреля

Используйте Хекслет по-максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»