Как создать двумерный массив с помощью NumPy в Python?

Что такое двумерный массив (матрица)?

Двумерный массив, или матрица, представляет собой структуру данных, организованную в виде строк и столбцов. Каждый элемент в матрице идентифицируется двумя индексами: номером строки и номером столбца. Матрицы широко используются для представления табличных данных, изображений (где каждый элемент представляет собой пиксель), а также для математических вычислений, например, в линейной алгебре.

Преимущества использования NumPy для работы с массивами

NumPy (Numerical Python) — это мощная библиотека Python, предназначенная для эффективной работы с массивами, особенно с многомерными. Основные преимущества использования NumPy:

  • Эффективность: NumPy массивы хранятся в памяти более компактно, чем стандартные списки Python, и операции над ними выполняются значительно быстрее.
  • Функциональность: NumPy предоставляет широкий набор функций для математических операций, линейной алгебры, преобразования массивов и многого другого.
  • Удобство: Синтаксис NumPy делает работу с массивами интуитивно понятной и простой.
  • Интеграция: NumPy легко интегрируется с другими библиотеками Python для анализа данных, такими как SciPy, pandas и scikit-learn.

Установка и импорт библиотеки NumPy

Прежде чем начать использовать NumPy, необходимо установить библиотеку. Это можно сделать с помощью pip:

pip install numpy

После установки NumPy импортируйте библиотеку в свой Python скрипт:

import numpy as np

Создание двумерных массивов с помощью NumPy

Использование numpy.array() для создания массивов из списков

Самый простой способ создать двумерный массив в NumPy — использовать функцию numpy.array(), передав ей в качестве аргумента список списков. Каждый внутренний список будет представлять собой строку массива.

import numpy as np
from typing import List

def create_array_from_lists(data: List[List[int]]) -> np.ndarray:
    """Creates a NumPy array from a list of lists.

    Args:
        data: A list of lists representing the array data.

    Returns:
        A NumPy array.
    """
    arr: np.ndarray = np.array(data)
    return arr

data: List[List[int]] = [[1, 2, 3], [4, 5, 6]]
arr: np.ndarray = create_array_from_lists(data)
print(arr)
# Output:
# [[1 2 3]
#  [4 5 6]]

Создание массивов заданной формы с помощью numpy.zeros() и numpy.ones()

Функции numpy.zeros() и numpy.ones() позволяют создать массивы, заполненные нулями и единицами соответственно. Первый аргумент определяет форму массива (количество строк и столбцов).

import numpy as np

def create_zeros_array(rows: int, cols: int) -> np.ndarray:
    """Creates a NumPy array filled with zeros.

    Args:
        rows: The number of rows in the array.
        cols: The number of columns in the array.

    Returns:
        A NumPy array filled with zeros.
    """
    arr: np.ndarray = np.zeros((rows, cols))
    return arr


def create_ones_array(rows: int, cols: int) -> np.ndarray:
    """Creates a NumPy array filled with ones.

    Args:
        rows: The number of rows in the array.
        cols: The number of columns in the array.

    Returns:
        A NumPy array filled with ones.
    """
    arr: np.ndarray = np.ones((rows, cols))
    return arr

zeros_array: np.ndarray = create_zeros_array(2, 3)
print(zeros_array)
# Output:
# [[0. 0. 0.]
#  [0. 0. 0.]]

ones_array: np.ndarray = create_ones_array(3, 2)
print(ones_array)
# Output:
# [[1. 1.]
#  [1. 1.]
#  [1. 1.]]

Генерация массивов с последовательностью значений: numpy.arange() и numpy.linspace()

Функция numpy.arange() создает одномерный массив с последовательностью значений, аналогично встроенной функции range(). Для создания двумерного массива, можно использовать reshape(), чтобы изменить форму.
numpy.linspace() создает массив с равномерно распределенными значениями в заданном интервале. Также полезно использовать reshape() для получения двумерной структуры.

import numpy as np

def create_arange_array(start: int, stop: int, step: int, rows: int, cols: int) -> np.ndarray:
    """Creates a NumPy array with a sequence of values using arange and reshapes it.

    Args:
        start: The start value of the sequence.
        stop: The end value of the sequence (exclusive).
        step: The step size.
        rows: The number of rows in the array.
        cols: The number of columns in the array.

    Returns:
        A NumPy array with the reshaped sequence.
    """
    arr: np.ndarray = np.arange(start, stop, step).reshape(rows, cols)
    return arr


def create_linspace_array(start: float, stop: float, num: int, rows: int, cols: int) -> np.ndarray:
    """Creates a NumPy array with evenly spaced values using linspace and reshapes it.

    Args:
        start: The start value of the sequence.
        stop: The end value of the sequence (inclusive).
        num: The number of evenly spaced values to generate.
        rows: The number of rows in the array.
        cols: The number of columns in the array.

    Returns:
        A NumPy array with the reshaped sequence.
    """
    arr: np.ndarray = np.linspace(start, stop, num).reshape(rows, cols)
    return arr


arange_array: np.ndarray = create_arange_array(0, 6, 1, 2, 3)
print(arange_array)
# Output:
# [[0 1 2]
#  [3 4 5]]

linspace_array: np.ndarray = create_linspace_array(0, 1, 6, 2, 3)
print(linspace_array)
# Output:
# [[0.  0.2 0.4]
#  [0.6 0.8 1. ]] 

Создание единичной матрицы с помощью numpy.eye()

Единичная матрица — это квадратная матрица, у которой все элементы на главной диагонали равны 1, а остальные элементы равны 0. Функция numpy.eye() позволяет создать единичную матрицу заданного размера.

import numpy as np

def create_identity_matrix(n: int) -> np.ndarray:
    """Creates a NumPy identity matrix.

    Args:
        n: The size of the identity matrix (number of rows and columns).

    Returns:
        A NumPy identity matrix.
    """
    identity_matrix: np.ndarray = np.eye(n)
    return identity_matrix


identity_matrix: np.ndarray = create_identity_matrix(3)
print(identity_matrix)
# Output:
# [[1. 0. 0.]
#  [0. 1. 0.]
#  [0. 0. 1.]]

Размеры и форма двумерных массивов

Определение размера массива: shape

Атрибут shape возвращает кортеж, содержащий размеры массива по каждой оси. Для двумерного массива shape вернет (количество строк, количество столбцов).

import numpy as np

def get_array_shape(arr: np.ndarray) -> tuple[int, ...]:
    """Returns the shape of a NumPy array.

    Args:
        arr: The NumPy array.

    Returns:
        A tuple representing the shape of the array.
    """
    return arr.shape

arr: np.ndarray = np.array([[1, 2, 3], [4, 5, 6]])
shape: tuple[int, ...] = get_array_shape(arr)
print(shape) # Output: (2, 3)

Изменение формы массива: reshape()

Метод reshape() позволяет изменить форму массива, не изменяя его данные. Важно, чтобы общее количество элементов в массиве оставалось прежним.

import numpy as np

def reshape_array(arr: np.ndarray, rows: int, cols: int) -> np.ndarray:
    """Reshapes a NumPy array.

    Args:
        arr: The NumPy array.
        rows: The new number of rows.
        cols: The new number of columns.

    Returns:
        A NumPy array with the new shape.

    Raises:
        ValueError: If the new shape is incompatible with the original size.
    """
    try:
        reshaped_array: np.ndarray = arr.reshape(rows, cols)
        return reshaped_array
    except ValueError as e:
        raise ValueError("Incompatible shape for reshaping.") from e


arr: np.ndarray = np.arange(6)
reshaped_arr: np.ndarray = reshape_array(arr, 2, 3)
print(reshaped_arr)
# Output:
# [[0 1 2]
#  [3 4 5]]
Реклама

Доступ к элементам и срезы двумерных массивов

Индексация элементов: доступ к конкретным значениям

Для доступа к элементам двумерного массива используется двойная индексация: array[номер_строки, номер_столбца]. Индексация начинается с 0.

import numpy as np

def access_element(arr: np.ndarray, row: int, col: int) -> int:
    """Accesses an element in a NumPy array using row and column indices.

    Args:
        arr: The NumPy array.
        row: The row index.
        col: The column index.

    Returns:
        The element at the specified row and column.
    """
    return arr[row, col]


arr: np.ndarray = np.array([[1, 2, 3], [4, 5, 6]])
element: int = access_element(arr, 0, 1)
print(element)  # Output: 2

Срезы: извлечение подмассивов

Срезы позволяют извлекать подмассивы из исходного массива. Синтаксис срезов: array[начало_строки:конец_строки, начало_столбца:конец_столбца]. Если начало или конец не указаны, подразумевается начало или конец массива соответственно.

import numpy as np

def get_subarray(arr: np.ndarray, row_start: int, row_end: int, col_start: int, col_end: int) -> np.ndarray:
    """Extracts a subarray from a NumPy array using slicing.

    Args:
        arr: The NumPy array.
        row_start: The starting row index.
        row_end: The ending row index (exclusive).
        col_start: The starting column index.
        col_end: The ending column index (exclusive).

    Returns:
        A NumPy subarray.
    """
    subarray: np.ndarray = arr[row_start:row_end, col_start:col_end]
    return subarray

arr: np.ndarray = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
subarray: np.ndarray = get_subarray(arr, 0, 2, 1, 3)
print(subarray)
# Output:
# [[2 3]
#  [5 6]]

Булева индексация: фильтрация элементов по условию

Булева индексация позволяет выбирать элементы массива, соответствующие определенному условию. Создается булев массив той же формы, что и исходный, где True соответствует элементам, удовлетворяющим условию, а False — нет. Затем этот булев массив используется для индексации исходного массива.

import numpy as np

def filter_array(arr: np.ndarray, condition: np.ndarray) -> np.ndarray:
    """Filters a NumPy array based on a boolean condition.

    Args:
        arr: The NumPy array.
        condition: A boolean array of the same shape as arr.

    Returns:
        A NumPy array containing elements where the condition is True.
    """
    filtered_array: np.ndarray = arr[condition]
    return filtered_array


arr: np.ndarray = np.array([[1, 2, 3], [4, 5, 6]])
condition: np.ndarray = arr > 3
print(condition)
# Output:
# [[False False False]
#  [ True  True  True]]

filtered_arr: np.ndarray = filter_array(arr, condition)
print(filtered_arr)
# Output:
# [4 5 6]

Примеры и практическое применение

Пример 1: Создание матрицы с заданными значениями

Представим, что нам нужно создать матрицу, представляющую посещаемость сайта по дням недели и часам дня. Строки соответствуют дням недели (понедельник — 0, вторник — 1 и т.д.), а столбцы – часам дня (0-23). Значения в матрице – количество посещений.

import numpy as np

def create_traffic_matrix(traffic_data: List[List[int]]) -> np.ndarray:
    """Creates a traffic matrix from a list of lists.

    Args:
        traffic_data: A list of lists representing the traffic data.

    Returns:
        A NumPy array representing the traffic matrix.
    """
    traffic_matrix: np.ndarray = np.array(traffic_data)
    return traffic_matrix


traffic_data: List[List[int]] = [
    [100, 120, 150, 130, 110, 90, 80, 70, 60, 50, 40, 30, 20, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110],
    [110, 130, 160, 140, 120, 100, 90, 80, 70, 60, 50, 40, 30, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120],
    [120, 140, 170, 150, 130, 110, 100, 90, 80, 70, 60, 50, 40, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130],
    [130, 150, 180, 160, 140, 120, 110, 100, 90, 80, 70, 60, 50, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140],
    [140, 160, 190, 170, 150, 130, 120, 110, 100, 90, 80, 70, 60, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150],
    [150, 170, 200, 180, 160, 140, 130, 120, 110, 100, 90, 80, 70, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160],
    [160, 180, 210, 190, 170, 150, 140, 130, 120, 110, 100, 90, 80, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170],
]

traffic_matrix: np.ndarray = create_traffic_matrix(traffic_data)
print(traffic_matrix)

Пример 2: Преобразование данных из файла в двумерный массив

Часто данные для анализа хранятся в файлах (например, CSV). NumPy позволяет легко загрузить данные из файла в двумерный массив.

import numpy as np

def load_data_from_file(filename: str, delimiter: str = ",") -> np.ndarray:
    """Loads data from a file into a NumPy array.

    Args:
        filename: The name of the file.
        delimiter: The delimiter used in the file (default: ",").

    Returns:
        A NumPy array containing the data from the file.

    Raises:
        FileNotFoundError: If the file does not exist.
        ValueError: If there is an issue loading the data.
    """
    try:
        data: np.ndarray = np.loadtxt(filename, delimiter=delimiter)
        return data
    except FileNotFoundError:
        raise FileNotFoundError(f"File not found: {filename}")
    except ValueError as e:
        raise ValueError(f"Error loading data from file: {e}")

# Create a dummy CSV file for demonstration
with open("data.csv", "w") as f:
    f.write("1,2,3\n")
    f.write("4,5,6\n")

# Load the data from the CSV file
data: np.ndarray = load_data_from_file("data.csv")
print(data)
# Output:
# [[1. 2. 3.]
#  [4. 5. 6.]]

Пример 3: Выполнение математических операций с матрицами

NumPy предоставляет широкий набор функций для выполнения математических операций с матрицами, таких как сложение, вычитание, умножение и транспонирование.

import numpy as np

def perform_matrix_operations(matrix1: np.ndarray, matrix2: np.ndarray) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
    """Performs matrix addition, subtraction, and multiplication.

    Args:
        matrix1: The first NumPy array.
        matrix2: The second NumPy array.

    Returns:
        A tuple containing the addition, subtraction, and element-wise multiplication results.

    Raises:
        ValueError: If the matrices have incompatible shapes for addition or subtraction.
    """
    try:
        addition_result: np.ndarray = matrix1 + matrix2
        subtraction_result: np.ndarray = matrix1 - matrix2
    except ValueError as e:
        raise ValueError("Matrices must have the same shape for addition and subtraction.") from e

    multiplication_result: np.ndarray = matrix1 * matrix2  # Element-wise multiplication
    return addition_result, subtraction_result, multiplication_result


matrix1: np.ndarray = np.array([[1, 2], [3, 4]])
matrix2: np.ndarray = np.array([[5, 6], [7, 8]])

addition_result, subtraction_result, multiplication_result = perform_matrix_operations(matrix1, matrix2)

print("Addition:\n", addition_result)
# Output:
# [[ 6  8]
#  [10 12]]

print("Subtraction:\n", subtraction_result)
# Output:
# [[-4 -4]
#  [-4 -4]]

print("Element-wise Multiplication:\n", multiplication_result)
# Output:
# [[ 5 12]
#  [21 32]]

Добавить комментарий