Панды отлично подходят для работы как с числовыми, так и с текстовыми данными. В большинстве проектов вам понадобится очистить и проверить ваши данные, прежде чем анализировать или использовать их для чего -либо полезного. Данные могут быть предоставлены в базах данных, CSV или других форматах файла данных, результатах сети или даже вручную. После того, как вы загрузили данные в Pandas, вам, вероятно, потребуется преобразовать их в тип, который имеет наибольший смысл для того, что вы пытаетесь достичь. В этом посте я собираюсь просмотреть основные данные дата в пандах и как безопасно и точно преобразовать данные.
DataFrame и ряд
Во -первых, давайте рассмотрим основные типы контейнеров в пандах, Серия
и DataFrame
Анкет A Серия
является одномерным меченным массивом данных, поддерживаемым Numpy
множество. A DataFrame
это двумерная структура, которая состоит из нескольких серийных столбцов, которые имеют индекс. Серия имеет тип данных, на который ссылаются как dtype
и все элементы в этом Серия
Поделится тем же типом.
Но какие типы?
Тип данных может быть ядром Numpy
DataType, что означает, что это может быть числовой тип или объект Python. Но тип также может быть типом расширения Pandas, известный как ExtensionDtype
. Не вдаваясь в слишком много деталей, просто знайте, что два очень распространенных примера – это CategoricalDtype
и в Pandas 1.0+, StringDtype
. На данный момент важно помнить, что все элементы в Серия
Поделиться тем же типом.
Важно понять, что при построении Серия
или DataFrame
, Pandas выберут тип данных, который может представлять все значения в Серия
(или DataFrame
). Давайте посмотрим на пример, чтобы прояснить это. Обратите внимание, что этот пример был запущен с помощью Pandas версии 1.1.4.
>>> import pandas as pd >>> s = pd.Series([1.0, 'N/A', 2]) >>> s 0 1 1 N/A 2 2 dtype: object
Как видите, Pandas выбрал объект
Тип для моего Серия
поскольку он может представлять значения, которые являются плавающими числами, строками и целыми числами. Отдельные элементы в этом Серия
все другой тип в этом случае, но могут быть представлены как объекты.
>>> print(type(s[0]))>>> print(type(s[1])) >>> print(type(s[2]))
Так в чем проблема?
Проблема с использованием объекта для всего состоит в том, что вы редко хотите работать со своими данными таким образом. Если посмотреть на этот первый пример, если бы вы импортировали эти данные из текстового файла, вы, скорее всего, хотели бы, чтобы они рассматривались как числовые, и, возможно, вычислите некоторые статистические значения из него.
>>> try: ... s.mean() ... except Exception as ex: ... print(ex) ... unsupported operand type(s) for +: 'float' and 'str'
Здесь ясно, что среднее
Функция не удается, потому что она пытается снять значения в Серия
и не может добавить «n/a» к запущенной сумме значений.
Так как же нам это исправить?
Что ж, мы могли бы осмотреть значения и преобразовать их вручную или использовать какую -то другую логику, но, к счастью, Pandas дает нам несколько вариантов, чтобы сделать это разумным образом. Давайте просмотрим их всех.
Астип
Во -первых, вы можете попробовать использовать Астип
для преобразования значений. Астип
однако ограничен, потому что, если оно не может преобразовать значение, оно либо увеличит ошибку, либо вернет исходное значение. Из -за этого это не может полностью помочь нам в этой ситуации.
>>> try: ... s.astype('float') ... except Exception as ex: ... print(ex) ... could not convert string to float: 'N/A'
Но Астип
очень полезен, поэтому, прежде чем двигаться дальше, давайте посмотрим на несколько примеров, где вы его используете. Во -первых, если бы все ваши данные были конвертируемыми между типами, это сделало бы именно то, что вы хотите.
>>> s2 = pd.Series([1, "2", "3.4", 5.5]) >>> print(s2) 0 1 1 2 2 3.4 3 5.5 dtype: object >>> print(s2.astype('float')) 0 1.0 1 2.0 2 3.4 3 5.5 dtype: float64
Второе, Астип
полезен для сохранения пространства в Серия
и DataFrame
S, особенно когда у вас есть повторяющиеся типы, которые могут быть выражены как категориальные . Категории могут сохранять память, а также сделать данные немного более читаемыми во время анализа, поскольку они сообщат вам все возможные значения. Например:
>>> s3 = pd.Series(["Black", "Red"] * 1000) >>> >>> s3.astype('category') 0 Black 1 Red 2 Black 3 Red 4 Black ... 1995 Red 1996 Black 1997 Red 1998 Black 1999 Red Length: 2000, dtype: category Categories (2, object): ['Black', 'Red'] >>> >>> print("String:", s3.memory_usage()) String: 16128 >>> print("Category:", s3.astype('category').memory_usage()) Category: 2224 >>>
Вы также можете сэкономить пространство, используя меньшие Numpy
типы
>>> s4 = pd.Series([22000, 3, 1, 9]) >>>s4.memory_usage() 160 >>> s4.astype('int8').memory_usage() 132
Но обратите внимание, что есть ошибка выше! Астип
С радостью преобразует номера, которые не вписываются в новый тип, не сообщая вам об ошибке.
>>> s4.astype('int8') 0 -16 1 3 2 1 3 9 dtype: int8
Обратите внимание, что вы также можете использовать Астип
на DataFrame
S, даже указание различных значений для каждого столбца
>>> df = pd.DataFrame({'a': [1,2,3.3, 4], 'b': [4, 5, 2, 3], 'c': ["4", 5.5, "7.09", 1]}) >>> df.astype('float') a b c 0 1.0 4.0 4.00 1 2.0 5.0 5.50 2 3.3 2.0 7.09 3 4.0 3.0 1.00 >>> df.astype({'a': 'uint', 'b': 'float16'}) a b c 0 1 4.0 4 1 2 5.0 5.5 2 3 2.0 7.09 3 4 3.0 1
to_numeric (или to_datetime или to_timedelta)
Есть несколько лучших вариантов, доступных в пандах для преобразования одномерных данных (то есть одна серия за раз). Эти методы обеспечивают лучшую коррекцию ошибок, чем
Астип
Через необязательный Ошибки
и вниз
параметры. Посмотрите, как это может иметь дело с первым Серия
создан в этом посте. Используя Приставление
Для ошибок превратит любые ошибки преобразования в НАН
Анкет Прохождение в игнорировать
Получит то же поведение, которое мы имели в Астип
, возвращая наш первоначальный ввод. Точно так же прохождение в поднять
поднимет исключение.
>>> pd.to_numeric(s, errors='coerce') 0 1.0 1 NaN 2 2.0 dtype: float64
И если мы хотим сэкономить немного места, мы можем безопасно понижать до минимального размера, который будет удерживать наши данные без ошибок (получение int16
вместо int64
Если мы не упали)
>>> pd.to_numeric(s4, downcast='integer') 0 22000 1 3 2 1 3 9 dtype: int16 >>> pd.to_numeric(s4).dtype dtype('int64')
to_dateTime
и to_timedelta
Методы будут вести себя одинаково, но для дат и времени.
>>> pd.to_numeric(s4).dtype dtype('int64') >>> pd.to_timedelta(['2 days', '5 min', '-3s', '4M', '1 parsec'], errors='coerce') TimedeltaIndex([ '2 days 00:00:00', '0 days 00:05:00', '-1 days +23:59:57', '0 days 00:04:00', NaT], dtype='timedelta64[ns]', freq=None) >>> pd.to_datetime(['11/1/2020', 'Jan 4th 1919', '20200930 08:00:31']) DatetimeIndex(['2020-11-01 00:00:00', '1919-01-04 00:00:00', '2020-09-30 08:00:31'], dtype='datetime64[ns]', freq=None)
Поскольку все эти функции предназначены для 1-мерных данных, вам нужно будет использовать применить
на DataFrame
. Например, чтобы понизить все значения до наименьшего возможного размера плавающей точки, используйте параметр Downcast.
>>> from functools import partial >>> df.apply(partial(pd.to_numeric, downcast='float')).dtypes a float32 b float32 c float32 dtype: object
adfer_objects
Если у вас есть объект Pandas, который состоит из объектов, которые еще не были преобразованы, оба Серия
и DataFrame
Есть метод, который попытается преобразовать эти объекты в самый разумный тип. Чтобы увидеть это, вы должны сделать своего рода надуманное пример, потому что пандам попытается преобразовать объекты при их создании. Например:
>>> pd.Series([1, 2, 3, 4], dtype='object').infer_objects().dtype int64 >>> pd.Series([1, 2, 3, '4'], dtype='object').infer_objects().dtype object >>>pd.Series([1, 2, 3, 4]).dtype int64
Здесь вы можете видеть, что если в серии есть все численные типы (в данном случае целых числа), но они хранятся как объекты, она может выяснить, как преобразовать их в целые числа. Но это не знает, как преобразовать «4» в целое число. Для этого вам нужно использовать одну из техник сверху.
convert_dtypes
Этот метод является новым в Pandas 1.0 и может преобразовать в наилучшие возможные dtype
что поддерживает ПД Na
Анкет Обратите внимание, что это будет Pandas dtype по сравнению с Numpy
dtype (т.е. int64
вместо int64
).
>>> pd.Series([1, 2, 3, 4], dtype='object').convert_dtypes().dtype Int64 >>> pd.Series([1, 2, 3, '4'], dtype='object').convert_dtypes().dtype object >>> pd.Series([1, 2, 3, 4]).convert_dtypes().dtype Int64
Что вы должны использовать чаще всего?
То, что я рекомендую сделать, это просмотреть ваши необработанные данные после того, как они импортируются. В зависимости от вашего источника данных, это может быть уже в желаемом DTYPE. Но как только вам нужно преобразовать его, у вас есть все инструменты, которые вам нужно сделать правильно. Для числовых типов Pd.to_numeric
Метод лучше всего подходит для выполнения этой конверсии безопасным образом, и с разумным использованием вниз
Параметр, вы также можете сэкономить место. Подумайте о использовании ASTYPE ("Категория")
Когда у вас есть повторяющиеся данные, чтобы сохранить пространство. convert_dtypes
и adfer_objects
Методы не будут такими полезными в большинстве случаев, если у вас каким -то образом нет данных, хранящихся как объекты, которые легко конвертируются в другой тип. Помните, что в пандах нет магической функции, которая бы обеспечит лучший тип данных для каждого случая, вам необходимо изучить и понять свои собственные данные для правильного их использования или анализа. Но знание того, что лучше всего сделать это преобразование, – отличное начало.
Оригинал: “https://dev.to/wrighter/converting-types-in-pandas-1l1k”