Python pandas column types

Обзор типов данных Pandas¶

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

Типы данных Pandas¶

Тип данных — это, по сути, внутреннее представление, которое язык программирования использует для понимания того, как данные хранить и как ими оперировать. Например, программа должна понимать, что вы хотите сложить два числа, например 5 + 10 , чтобы получить 15 . Или, если у вас есть две строки, такие как «кошка» и «шляпа» вы можете объединить (сложить) их вместе, чтобы получить «кошкашляпа» .

Проблема с типами данных pandas заключается в том, что между pandas, Python и NumPy существует некоторое совпадение.

В следующей таблице приведены основные ключевые моменты:

Pandas Python NumPy Использование
object str или смесь string, unicode, смешанные типы Текстовые или смешанные числовые и нечисловые значения
int64 int int_, int8, int16, int32, int64, uint8, uint16, uint32, uint64 Целые числа
float64 float float_, float16, float32, float64 Числа с плавающей точкой
bool bool bool_ Значения True/False
datetime64 datetime datetime64[ns] Значения даты и времени
timedelta[ns] NA NA Разность между двумя datetimes
category NA NA Ограниченный список текстовых значений

В этом Блокноте я сосредоточусь на следующих типах данных pandas:

Про тип category смотрите в отдельной статье.

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

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

Почему нас это волнует?¶

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

Я буду использовать очень простой CSV файл, чтобы проиллюстрировать пару распространенных ошибок, которые вы можете встретить.

import pandas as pd import numpy as np 
df = pd.read_csv("https://github.com/dm-fedorov/pandas_basic/blob/master/%D0%B1%D1%8B%D1%81%D1%82%D1%80%D0%BE%D0%B5%20%D0%B2%D0%B2%D0%B5%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5%20%D0%B2%20pandas/data/sales_data_types.csv?raw=True") 
Customer Number Customer Name 2016 2017 Percent Growth Jan Units Month Day Year Active
0 10002.0 Quest Industries $125,000.00 $162500.00 30.00% 500 1 10 2015 Y
1 552278.0 Smith Plumbing $920,000.00 $101,2000.00 10.00% 700 6 15 2014 Y
2 23477.0 ACME Industrial $50,000.00 $62500.00 25.00% 125 3 29 2016 Y
3 24900.0 Brekke LTD $350,000.00 $490000.00 4.00% 75 10 27 2015 Y
4 651029.0 Harbor Co $15,000.00 $12750.00 -15.00% Closed 2 2 2014 N
Читайте также:  React native css after

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

Сложим продажи за 2016 и 2017 годы:

0 $125,000.00$162500.00 1 $920,000.00$101,2000.00 2 $50,000.00$62500.00 3 $350,000.00$490000.00 4 $15,000.00$12750.00 dtype: object

Выглядит странно. Мы хотели суммировать значения столбцов, но pandas их объединил, чтобы создать одну длинную строку.

Ключ к разгадке проблемы — это строка, в которой написано dtype: object .

object — это строка в pandas, поэтому он выполняет строковую конкатенацию вместо математического сложения.

Если мы хотим увидеть все типы данных, которые находятся в кадре данных ( DataFrame ), то воспользуемся атрибутом dtypes :

Customer Number float64 Customer Name object 2016 object 2017 object Percent Growth object Jan Units object Month int64 Day int64 Year int64 Active object dtype: object

Кроме того, функция df.info() показывает много полезной информации:

 RangeIndex: 5 entries, 0 to 4 Data columns (total 10 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Customer Number 5 non-null float64 1 Customer Name 5 non-null object 2 2016 5 non-null object 3 2017 5 non-null object 4 Percent Growth 5 non-null object 5 Jan Units 5 non-null object 6 Month 5 non-null int64 7 Day 5 non-null int64 8 Year 5 non-null int64 9 Active 5 non-null object dtypes: float64(1), int64(3), object(6) memory usage: 528.0+ bytes

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

  • Customer Number (Номер клиента) — float64 , но должен быть int64 .
  • Столбцы 2016 и 2017 хранятся как objects , а не числовые значения, такие как float64 или int64 .
  • Percent Growth (Единицы процентного роста) и Jan Units также хранятся как objects , а не числовые значения.
  • У нас есть столбцы Month , Day и Year , которые нужно преобразовать в datetime64 .
  • Столбец Active должен быть логическим ( boolean ).

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

  • Используйте метод astype() , чтобы принудительно задать тип данных.
  • Создайте настраиваемую (custom) функцию для преобразования данных.
  • Используйте функции to_numeric() или to_datetime() .
Читайте также:  Analyze java thread dump

Использование функции astype()¶

Самый простой способ преобразовать столбец данных в другой тип — использовать astype() . Например, чтобы преобразовать Customer Number (Номер клиента) в целое число, можем сделать так:

df['Customer Number'].astype('int') # pandas понимает, что в итоге нужен int64 
0 10002 1 552278 2 23477 3 24900 4 651029 Name: Customer Number, dtype: int64

Чтобы изменить Customer Number в исходном кадре данных, обязательно присвойте его обратно столбцу, так как функция astype() возвращает копию:

df["Customer Number"] = df['Customer Number'].astype('int') df.dtypes 
Customer Number int64 Customer Name object 2016 object 2017 object Percent Growth object Jan Units object Month int64 Day int64 Year int64 Active object dtype: object

А вот новый кадр данных с Customer Number в качестве целого числа:

Customer Number Customer Name 2016 2017 Percent Growth Jan Units Month Day Year Active
0 10002 Quest Industries $125,000.00 $162500.00 30.00% 500 1 10 2015 Y
1 552278 Smith Plumbing $920,000.00 $101,2000.00 10.00% 700 6 15 2014 Y
2 23477 ACME Industrial $50,000.00 $62500.00 25.00% 125 3 29 2016 Y
3 24900 Brekke LTD $350,000.00 $490000.00 4.00% 75 10 27 2015 Y
4 651029 Harbor Co $15,000.00 $12750.00 -15.00% Closed 2 2 2014 N

Все это выглядит хорошо и кажется довольно простым.

Давайте попробуем проделать то же самое со столбцом 2016 и преобразовать его в число с плавающей точкой:

# здесь появится исключение: # df['2016'].astype('float') 

Аналогичным образом мы можем попытаться преобразовать столбец Jan Units в целое число:

# здесь тоже появится исключение: # df['Jan Units'].astype('int') 

Оба примера возвращают исключения ValueError , т.е. преобразования не сработали.

В каждом из случаев данные включали значения, которые нельзя было интерпретировать как числа. В столбцах продаж данные включают символ валюты $ , а также запятую. В столбце Jan Units последним значением является Closed (Закрыто), которое не является числом; так что мы получаем исключение.

Пока что astype() как инструмент для преобразования выглядит не очень хорошо.

Мы должны попробовать еще раз в столбце Active .

0 True 1 True 2 True 3 True 4 True Name: Active, dtype: bool

На первый взгляд все выглядит нормально, но при ближайшем рассмотрении обнаруживается проблема. Все значения были интерпретированы как True , но последний клиент в столбце Active имеет флаг N вместо Y .

Читайте также:  Java array size long

Вывод из этого раздела такой — astype() будет работать, если:

  • данные чистые и могут быть просто интерпретированы как число;
  • вы хотите преобразовать числовое значение в строковый объект, т.е. вызвать astype(‘str’) .

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

Дополнительно¶

Отметим, что astype() может принимать словарь имен столбцов и типов данных:

df.astype('Customer Number': 'int', 'Customer Name': 'str'>).dtypes 
Customer Number int64 Customer Name object 2016 object 2017 object Percent Growth object Jan Units object Month int64 Day int64 Year int64 Active object dtype: object

Пользовательские функции преобразования¶

Поскольку эти данные немного сложнее преобразовать, можно создать настраиваемую (custom) функцию, которую применим к каждому значению и преобразовать в соответствующий тип данных.

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

def convert_currency(val): """ Преобразует числовое значение строки в число с плавающей точкой: - удаляет $ - удаляет запятые - преобразует в число с плавающей точкой """ new_val = val.replace(',', '').replace('$', '') return float(new_val) 

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

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

Также следует отметить, что функция преобразует число в питоновский float , но pandas внутренне преобразует его в float64 . Как упоминалось ранее, я рекомендую разрешить pandas выполнять такие преобразования. Вам не нужно пытаться понижать до меньшего или повышать до большего размера байта, если вы действительно не знаете, зачем это нужно.

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

Источник

Оцените статью