- Обзор типов данных Pandas¶
- Типы данных Pandas¶
- Почему нас это волнует?¶
- Использование функции astype()¶
- Дополнительно¶
- Пользовательские функции преобразования¶
- Как преобразовать объект в плавающий в pandas (с примерами)
- Способ 1: используйте astype() для преобразования объекта в число с плавающей запятой
- Способ 2: используйте to_numeric() для преобразования объекта в число с плавающей запятой
- Дополнительные ресурсы
Обзор типов данных 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 |
На первый взгляд данные выглядят нормально, поэтому попробуем выполнить некоторые операции.
Сложим продажи за 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() .
Использование функции 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 .
Вывод из этого раздела такой — 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 .
Как преобразовать объект в плавающий в pandas (с примерами)
Вы можете использовать один из следующих методов для преобразования столбца в pandas DataFrame из объекта в плавающий:
Способ 1: Используйте astype()
df['column_name'] = df['column_name'].astype (float)
Способ 2: Используйте to_numeric()
df['column_name'] = pd.to_numeric(df['column_name'])
Оба метода дают одинаковый результат.
В следующих примерах показано, как использовать каждый метод со следующими пандами DataFrame:
import pandas as pd #create DataFrame df = pd.DataFrame() #view DataFrame print(df) team points assists 0 A 18 5 1 B 22.2 7 2 C 19.1 7 3 D 14 9 4 E 14 12 5 F 11.5 9 6 G 20 9 7 H 28 4 #check data type of each column print(df.dtypes ) team object points object assists int64 dtype: object
Способ 1: используйте astype() для преобразования объекта в число с плавающей запятой
В следующем коде показано, как использовать функцию astype() для преобразования столбца точек в DataFrame из объекта в число с плавающей запятой:
#convert points column from object to float df['points'] = df['points'].astype (float) #view updated DataFrame print(df) team points assists 0 A 18.0 5 1 B 22.2 7 2 C 19.1 7 3 D 14.0 9 4 E 14.0 12 5 F 11.5 9 6 G 20.0 9 7 H 28.0 4 #view updated data types print(df.dtypes ) team object points float64 assists int64 dtype: object
Обратите внимание, что столбец точек теперь имеет тип данных float64 .
Способ 2: используйте to_numeric() для преобразования объекта в число с плавающей запятой
В следующем коде показано, как использовать функцию to_numeric() для преобразования столбца точек в DataFrame из объекта в число с плавающей запятой:
#convert points column from object to float df['points'] = pd.to_numeric(df['points'], errors='coerce') #view updated DataFrame print(df) team points assists 0 A 18.0 5 1 B 22.2 7 2 C 19.1 7 3 D 14.0 9 4 E 14.0 12 5 F 11.5 9 6 G 20.0 9 7 H 28.0 4 #view updated data types print(df.dtypes ) team object points float64 assists int64 dtype: object
Обратите внимание, что столбец точек теперь имеет тип данных float64 .
Также обратите внимание, что этот метод дает точно такой же результат, как и предыдущий метод.
Дополнительные ресурсы
В следующих руководствах объясняется, как выполнять другие распространенные задачи в pandas: