Как преобразовать массив в число python
Перейти к содержимому

Как преобразовать массив в число python

  • автор:

Переформатирование, изменение формы — Python: Numpy-массивы

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

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

Как изменить размер массива

Представим, что нам нужно увеличить размер массива numpy.ndarray . Для этого будем идти по следующим шагам:

  1. Узнаем размер массива и индексы вдоль оси
  2. Изменим размер массива

Рассмотрим каждый этап подробнее.

Как узнать размер массива и индексы вдоль оси

Чтобы изменить размер numpy.ndarray , нужно узнать его значение. Для этого используют атрибут shape :

import numpy as np one_dimension_array = np.array( [0,1,2,3,4,5,6,7,8,9,10,11] ) print(one_dimension_array.shape) # => (12,) two_dimensions_array = np.array( [ [0,1,2], [3,4,5], [6,7,8], [9,10,11] ] ) print(two_dimensions_array.shape) # => (4, 3) three_dimensions_array = np.array( [ [ [0,1], [2,3], ], [ [4,5], [6,7], ], [ [8,9], [10,11] ] ] ) print(three_dimensions_array.shape) # => (3, 2, 2) 

В примере выше атрибут shape возвращает кортеж целых чисел. Длина кортежа указывает на размерность массива:

  • (12,) — одномерный массив
  • (4, 3) — двумерный массив
  • (3, 2, 2) — трехмерный массив

Числа в кортеже означают количество элементов по конкретной оси индексов:

  • (12,) — 12 значений
  • (4, 3) — четыре блока значений по три значения в каждом
  • (3, 2, 2) — три блока значений, каждый из которых состоит из двух блоков по два значения

Название ось индексов отсылает к декартовой системе координат. Вспомним ее основные правила:

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

Теперь, когда мы знаем размер исходного массива, можно изменять его форму. Для этого используем метод reshape() .

Как изменить размер массива с помощью метода reshape()

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

Попробуем получить двумерный массив two_dimensions_array из одномерного массива one_dimension_array . Для этого используем метод reshape() с новым размером данных (4, 3) :

print(one_dimension_array.reshape((4, 3))) # => [[ 0 1 2] # [ 3 4 5] # [ 6 7 8] # [ 9 10 11]] 

Чтобы получить трехмерный массив three_dimensions_array , достаточно также указать нужный размер:

print(one_dimension_array.reshape((3, 2, 2))) # => [[[ 0 1] # [ 2 3]] # [[ 4 5] # [ 6 7]] # [[ 8 9] # [10 11]]] 

Изменять форму массива можно не только от данных меньшей размерности к данным большей размерности. Это можно делать и в обратную сторону.

Попробуем получить исходный одномерный массив one_dimension_array из двумерного массива two_dimensions_array :

print(two_dimensions_array.reshape((12,))) # => [ 0 1 2 3 4 5 6 7 8 9 10 11] 

А тут переформатируем three_dimensions_array в two_dimensions_array :

print(three_dimensions_array.reshape((4,3))) # => [[ 0 1 2] # [ 3 4 5] # [ 6 7 8] # [ 9 10 11]] 

Необязательно уменьшать размер последовательно. Например, можно из трехмерного массива получить сразу одномерный:

print(three_dimensions_array.reshape((12,))) # => [ 0 1 2 3 4 5 6 7 8 9 10 11] 

С помощью атрибута shape можно узнать размерность массива numpy.ndarray . А метод reshape поможет ее уменьшить или увеличить. Однако у этого массива есть ограничения по размеру данных — его нужно соблюдать, чтобы оптимизировать выполнения методов над массивами.

Какие размеры массива допустимы

У массива numpy.ndarray есть ограничения по размеру данных — по осям индексов должны быть данные одного размера. Это ограничение позволяет оптимизировать выполнения методов над массивами. Рассмотрим на примере.

Допустим, нам нужно сконвертировать список из списков длиной три и два:

np.array( [ [0,1,2], [3,4,], ] ) # => [list([0, 1, 2]) list([3, 4])] 

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

Попробуем найти в данном массиве максимальный элемент 4 . Это приведет к такому результату:

print(np.array( [ [0,1,2], [3,4,], ] ).max()) # => [3, 4] 

В этом примере мы получили не тот результат, которого ожидали.

Numpy старается предотвращать некорректные действия — для этого в нем есть система предупреждений и подсказок. Но это не значит, что не нужно следить за размером массива. Он играет важную роль в реализации методов библиотеки Numpy, поэтому рекомендуем обращать внимание на этот момент.

В случае с методом reshape() Numpy вообще не дает совершить некорректную конвертацию массива из 12 элементов в массив из 15 элементов — три блока по пять значений. В этом случае он вызывает исключение:

one_dimension_array.reshape(3,5) # => ValueError: cannot reshape array of size 12 into shape (3,5) 

Ограничения по размеру могут добавить неудобств, когда мы увеличиваем или уменьшаем размерность массива. При этом они позволяют не указывать некоторые значения размера, когда мы хотим его изменить.

Как сделать автоматический расчет размера массива

Ограничения на размер массива позволяют не указывать некоторые размеры в методе reshape() . Это можно оставить на автоматический расчет. Для этого нужное значение размерности поменяем на -1 :

print(one_dimension_array.reshape((4,3))) print(one_dimension_array.reshape(((4, -1)))) print(one_dimension_array.reshape(((-1, 3)))) # => [[ 0 1 2] # [ 3 4 5] # [ 6 7 8] # [ 9 10 11]] 

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

Для массивов большей размерности это работает по такому же принципу:

print(one_dimension_array.reshape((3, 2, 2))) print(one_dimension_array.reshape((-1, 2, 2))) print(one_dimension_array.reshape((3, -1, 2))) print(one_dimension_array.reshape((3, 2, -1))) # => [[[ 0 1] # [ 2 3]] # [[ 4 5] # [ 6 7]] # [[ 8 9] # [10 11]]] 

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

print(three_dimensions_array.reshape((12,))) print(three_dimensions_array.reshape((-1,))) # => [ 0 1 2 3 4 5 6 7 8 9 10 11] 

Теперь вы знаете, как определять размерность массива. Вы умеете изменять размер и рассчитывать его автоматически. Чтобы закрепить знания на практике, рассмотрим еще один пример.

Как размер массива меняется на практике

Изменение формы массива помогает подготовить исходные данные — после такой обработки их будет удобнее анализировать и преобразовывать.

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

orders = [7, 1, 7, 8, 4, 2, 4, 5, 3, 5, 2, 3, 8, 12, 8, 7, 15, 11, 13, 9, 21, 18, 17, 21, 25, 16, 25, 17,] shops_number = 4 orders_matrix = np.array(orders) orders_matrix = orders_matrix.reshape(-1, shops_number) print(orders_matrix) # => [[ 7 1 7 8] # [ 4 2 4 5] # [ 3 5 2 3] # [ 8 12 8 7] # [15 11 13 9] # [21 18 17 21] # [25 16 25 17]] print(orders_matrix.shape) # => (7, 4) 

Полученный массив данных можно визуализировать в виде такой таблицы:

День Магазин №1 Магазин №2 Магазин №3 Магазин №4
0 7 1 7 8
1 4 2 4 5
2 3 5 2 3
3 8 12 8 7
4 15 11 13 9
5 21 18 17 21
6 25 16 25 17

Выводы

Метод shape — важный атрибут для структурного описания массива numpy.ndarray . Он помогает узнать размер вдоль каждой оси.

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

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

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов

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

Массивы

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

Раньше мы сталкивались с задачей обработки элементов последовательности, например, вычисляя наибольший элемент последовательности. Но при этом мы не сохраняли всю последовательность в памяти компьютера, однако, во многих задачах нужно именно сохранять всю последовательность, например, если бы нам требовалось вывести все элементы последовательности в возрастающем порядке (“отсортировать последовательность”).

Для хранения таких данных можно использовать структуру данных, называемую в Питоне список (в большинстве же языков программирования используется другой термин “массив”). Список представляет собой последовательность элементов, пронумерованных от 0, как символы в строке. Список можно задать перечислением элементов списка в квадратных скобках, например, список можно задать так:

Primes = [2, 3, 5, 7, 11, 13]
Rainbow = ['Red', 'Orange', 'Yellow', 'Green', 'Blue', 'Indigo', 'Violet']

В списке Primes — 6 элементов, а именно, Primes[0] == 2, Primes[1] == 3, Primes[2] == 5, Primes[3] == 7, Primes[4] == 11, Primes[5] == 13. Список Rainbow состоит из 7 элементов, каждый из которых является строкой.

Также как и символы строки, элементы списка можно индексировать отрицательными числами с конца, например, Primes[-1] == 13, Primes[-6] == 2.

Длину списка, то есть количество элементов в нем, можно узнать при помощи функции len, например, len(A) == 6.

Рассмотрим несколько способов создания и считывания списков. Прежде всего можно создать пустой список (не содержащий элементов, длины 0), в конец списка можно добавлять элементы при помощи метода append. Например, если программа получает на вход количество элементов в списке n, а потом n элементов списка по одному в отдельной строке, то организовать считывание списка можно так:

A = []
for i in range(int(input()):
A.append(int(input())

В этом примере создается пустой список, далее считывается количество элементов в списке, затем по одному считываются элементы списка и добавляются в его конец.

Для списков целиком определены следующие операции: конкатенация списков (добавление одного списка в конец другого) и повторение списков (умножение списка на число). Например:

A = [1, 2, 3]
B = [4, 5]
C = A + B
D = B * 3

В результате список C будет равен [1, 2, 3, 4, 5], а список D будет равен [4, 5, 4, 5, 4, 5]. Это позволяет по-другому организовать процесс считывания списков: сначала считать размер списка и создать список из нужного числа элементов, затем организовать цикл по переменной i начиная с числа 0 и внутри цикла считывается i-й элемент списка:

A = [0] * int(input())
for i in range(len(A)):
A[i] = int(input())

Вывести элементы списка A можно одной инструкцией print(A), при этом будут выведены квадратные скобки вокруг элементов списка и запятые между элементами списка. Такой вывод неудобен, чаще требуется просто вывести все элементы списка в одну строку или по одному элементу в строке. Приведем два примера, также отличающиеся организацией цикла:

for i in range(len(A)): 
print(A[i])

Здесь в цикле меняется индекс элемента i, затем выводится элемент списка с индексом i.

for elem in A: 
print(elem, end = ' ')

В этом примере элементы списка выводятся в одну строку, разделенные пробелом, при этом в цикле меняется не индекс элемента списка, а само значение переменной (например, в цикле for elem in [‘red’, ‘green’, ‘blue’] переменная elem будет последовательно принимать значения ‘red’, ‘green’, ‘blue’.

Как преобразовать массив в число?

user49913 Просветленный (38592) УМВР

Остальные ответы

x = [1, 2, 3]
print(int(».join(map(str, x))))
Естественно будет ошибка, если в массиве будут присутствовать не числа.
Чтобы не было ошибки:
x = [1, 2, 3, «string»]
print(int(».join([i for i in map(str, x) if i.isdigit()])))
>>123

Похожие вопросы
Ваш браузер устарел

Мы постоянно добавляем новый функционал в основной интерфейс проекта. К сожалению, старые браузеры не в состоянии качественно работать с современными программными продуктами. Для корректной работы используйте последние версии браузеров Chrome, Mozilla Firefox, Opera, Microsoft Edge или установите браузер Atom.

Перевод списка строк в список чисел

Во многих языках когда используется цикл вида for-in элементы оисходной последовательности являются неизменяемыми. То есть вы имеете дело с копиями элементов. Я не знаю Python, но, думаю, здесь имеет место тоже самое.

18 окт 2015 в 21:13
Возможно, вам будет полезен этот ответ
18 окт 2015 в 22:50

5 ответов 5

Сортировка: Сброс на вариант по умолчанию

Наиболее идиоматический и идеологически выверенный способ:

result = [int(item) for item in a] 

Для любителей функционального стиля:

result = list(map(int, a)) 

Тут функция map применяет функцию int к каждому элементу объекта a , потом результат преобразовывается в список.

Такой вариант считается менее «питоничным», но тоже имеет право на существование (как минимум, во многих случаях запись через map получается более компактной, чем вариант через списочное выражение).

По поводу вашего первого варианта: когда вы пишете for el in a , то каждый раз в цикле в el записывается ссылка на элемент списка. Но когда вы пишете el = int(el) , то в переменную el просто записывается другая ссылка, сам элемент списка не меняется.

Как понять, что это именно ссылка, а не копия элемента? Вот пример, как при помощи вызова метода элемента списка меняется сам элемент:

>>> a = [[], [], []] >>> for el in a: el.append(1) >>> a [[1], [1], [1]] 

По поводу вашего ответа, перебор со счетчиком (если он вам вдруг действительно понадобится) на Python правильнее (проще и приятнее, без всяких len вложенных в range) делать через enumerate:

for i, item in enumerate(a): a[i] = int(item) 

Отслеживать
ответ дан 18 окт 2015 в 23:22
49k 17 17 золотых знаков 56 56 серебряных знаков 100 100 бронзовых знаков

Различные способы выполнить это преобразование:

    Изменяя непосредственно элементы массива

for i, elem in enumerate(array): array[i] = int(elem) 
array = [int(elem) for elem in array] 
array = list(map(int, array)) 

Вот более подробное объяснение происходящего:

Для начала вспомним, что все переменные в Python являются ссылками на объекты.

Пусть у нас будет массив array со следующим содержимым:

array = ['10', '11', '12'] 

Вот как это будет представляться в памяти в Python ( idN — это адрес объекта в памяти):

визуализация массива

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

Когда вы перебираете значения в цикле, например,

for elem in array: elem = int(elem) 

На каждой итерации переменная elem просто будет указывать на текущее число массива array .

Например, на первой итерации:

elem указывает на первую строку

Если мы попробуем присвоить что-то переменной elem , то мы просто заменим то, на что она будет указывать на текущей итерации цикла:

elem указывает на новый объект

Заметьте, что в массиве при этом ссылка не меняется, и нулевой элемент как указывал на строку «10» , так и продолжает на неё указывать:

array[0] указывает всё ещё на старый объект

Т.е. наша задача на самом деле заключается в том, чтобы заменить ссылку, хранящуюся в списке array на новую, т.е. в нашей визуализации на id5 .

Чтобы это сделать, нам нужно получить доступ на запись в конкретную ячейку списка. Список позволяет сделать это через доступ по индексу. Напишем следующий код (подобный которому как раз используется вами в собственном ответе):

array = ['10', '11', '12'] for i in range(len(array)): old_value = array[i] new_value = int(old_value) array[i] = new_value 

Я расписал в несколько строк для наглядности.

Здесь на первой итерации цикла мы получаем переменную i , хранящую не ссылку на строку, а позицию в списке array , в которой нам нужно заменить ссылку:

переменная i хранит число 0, а не ссылку на строку

Далее получаем строку, хранящуюся по этому индексу для того, чтобы преобразовать её в число (здесь она сохраняется в отдельной переменной, в вашем коде это будет временный объект):

old_value = array[i] 

old_value указывает на строку в списке

Имея значение элемента, мы можем выполнить над ним интересующую нас операцию. Снова сохраним его в отдельной переменной.

new_value = int(old_value) 

new_value указывает на полученное число

Имея новое значение и индекс, по которому его нужно сохранить в нашем списке, у нас не остаётся проблем, чтобы завершить выполнение итерации, сохранив новое значение в нужном месте:

array[i] = new_value 

изменили первое значение в списке

Таким образом и производится изменение значений массива.

Приведу для сравнения краткую запись этого кода:

for i in range(len(array)): array[i] = int(array[i]) 

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

Если скомбинировать оба этих способа, можно получить немного более удобную запись этого же преобразования:

for i, elem in enumerate(array): array[i] = int(elem) 

Функция enumerate для нашего списка вернёт последовательность вида

[(0, '10'), (1, '11'), (2, '12')] 

Такой цикл избавляет нас от необходимости писать самостоятельно доступ по индексу массива. Важно понимать, что переменная elem и здесь не даёт нам доступа на запись в массив, она просто хранит указатель на объект, хранящийся по текущему индексу в списке.

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

Такие ситуации встречаются, например, когда мы пишем функцию, которая должна изменить значения в переданном списке вместо создания нового.

Если же нам не требуется изменять этот список, а достаточно создания нового, в котором будут храниться целочисленные представления соответствущих элементов, то можно воспользоваться встроенной функцией map , как предложил @ReinRaus:

array = list(map(int, array)) 

Только стоит помнить, что в Python 3 функция map возвращает генератор, поэтому стоит явно преобразовать результат в список.

Ещё один удобный способ получения такого же результата, это использование генератора списков:

array = [int(elem) for elem in array] 

Оба этих решения эквивалентны и являются аналогом следующего кода:

result_array = [] for elem in array: result_array.append(int(elem)) array = result_array 

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

Продемострирую разницу этих способов на примере:

array = ['10', '11', '12'] link = array 

Важно понимать, что здесь обе переменные будут указывать на один и тот же список, а не являться двумя списками с одинаковыми значениями (здесь все ссылки явно отрисованы стрелками):

обе переменных указывают в одно и то же место

Выполним преобразование, изменяя элементы списка:

array = ['10', '11', '12'] link = array print(array, link) # ['10', '11', '12'] ['10', '11', '12'] for i, elem in enumerate(array): array[i] = int(elem) print(array, link) # [10, 11, 12] [10, 11, 12] 

Как мы видим, массив непосредственно изменился, а вместе с ним изменились данные, которые доступны по переменным, указывающим на этот список:

изменились значения элементов списка

Если же воспользоваться вторым способом

array = ['10', '11', '12'] link = array print(array, link) # ['10', '11', '12'] ['10', '11', '12'] array = list(map(int, array)) print(array, link) # [10, 11, 12] ['10', '11', '12'] 

то ещё по выводу программы можно заметить, что содержимое исходного списка не изменилось. Итоговая картина объектов будет выглядеть так:

введите сюда описание изображения

Мы видим, что был создан новый список, в котором были сохранены числовые представления значений исходного.

Для визуализации использовался сервис pythontutor.com.

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *