Типы данных Pandas (dtype и преобразование типов)

Pandas предоставляет богатую систему типов данных. Правильное понимание и использование типов данных — основа эффективного анализа данных. В этом разделе подробно рассматриваются система типов данных Pandas, вывод типов и методы преобразования типов.


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

dtype Описание Тип Python Пример
int64 64-битное целое число int 1, 2, 100
float64 64-битное число с плавающей точкой float 1.5, 3.14
object Строка или смешанный тип str "hello"
bool Boolean bool True, False
datetime64[ns] Datetime datetime 2024-01-01
timedelta64[ns] Timedelta timedelta 1 days
category Категориальный тип - Конечное множество

Пример

import pandas as pd
import numpy as np

# Создать DataFrame с различными типами данных
df = pd.DataFrame({
    "Целое": [1, 2, 3],
    "Вещественное": [1.5, 2.5, 3.5],
    "Строка": ["a", "b", "c"],
    "Логическое": [True, False, True],
    "Дата": pd.date_range("2024-01-01", periods=3)
})

print("Типы данных столбцов:")
print(df.dtypes)

Вывод и указание типов

Автоматический вывод типов

Пример

import pandas as pd

# Вывод типов при чтении CSV
# pandas пытается определить наиболее подходящий тип для каждого столбца
df = pd.read_csv("data.csv")

# Или используйте параметр dtype для явного указания типов
df = pd.read_csv("data.csv", dtype={
    "Age": "int32",     # Укажите как 32-битное целое, чтобы сэкономить память
    "Salary": "float32",   # Укажите как 32-битное число с плавающей запятой
    "Name": "string"     # Использовать строку PyArrow
})

Указание типов при создании

Пример

import pandas as pd
import numpy as np

# Укажите тип данных для создания Series
s = pd.Series([1, 2, 3], dtype="int8")  # Используйте меньший целочисленный тип
print(f"тип int8: {s.dtype}")

s = pd.Series([1.5, 2.5, 3.5], dtype="float32")  # Используйте float32
print(f"тип float32: {s.dtype}")

# Используйте тип numpy
s = pd.Series([1, 2, 3], dtype=np.int8)
print(f"тип np.int8: {s.dtype}")

Преобразование типов

Преобразование с помощью astype

Пример

import pandas as pd
import numpy as np

# Создание тестовых данных
df = pd.DataFrame({
    "Целое": [1, 2, 3],
    "Вещественное": [1.5, 2.5, 3.5],
    "Строка": ["1", "2", "3"],
    "Boolean": [1, 0, 1]
})

print("Исходные типы:")
print(df.dtypes)
print()

# Преобразовать в строку
df["Integer_str"] = df["Integer"].astype(str)
print("После преобразования в строку:")
print(df.dtypes)

# Преобразовать строку в числовой тип
df["String_int"] = df["String"].astype(int)
print("\n"Строка в целое число:")
print(df.dtypes)

# Преобразовать числовой тип в boolean (ненулевое — True)
df["Boolean_int"] = df["Boolean"].astype(bool)
print("\n"Целое число в boolean:")
print(df.dtypes)

# Преобразовать float в целое (усечение)
df["Float_int"] = df["Float"].astype(int)
print("\n"Float в целое:")
print(df)

Преобразование с помощью pd.to_numeric

Пример

import pandas as pd
import numpy as np

# Обработка числовых строк со специальными символами
s = pd.Series(["$1,000", "$2,500", "$3,200"])

# Очистка и преобразование
s_cleaned = s.str.replace("$", "", regex=False).str.replace(",", "", regex=False)
s_numeric = pd.to_numeric(s_cleaned)
print("Строка в числовой формат:")
print(s_numeric)
print(f"Тип: {s_numeric.dtype}")
print()

# Обработка пропущенных значений
s_with_na = pd.Series(["1", "2", "NA", "4"])
s_numeric = pd.to_numeric(s_with_na, errors="coerce")  # Преобразование недопустимых значений в NaN
print("Обработка пропущенных значений:")
print(s_numeric)

Преобразование дат с помощью pd.to_datetime

Пример

import pandas as pd

# Преобразование различных форматов дат
dates = ["2024-01-01", "2024/01/02", "01/03/2024", "20240104"]

# Преобразование дат
dt = pd.to_datetime(dates, errors="coerce")
print("Результат преобразования дат:")
print(dt)
print(f"Тип: {dt.dtype}")
print()

# Указать формат даты
dates2 = ["20240101", "20240102", "20240103"]
dt2 = pd.to_datetime(dates2, format="%Y%m%d")
print("Преобразование с указанным форматом:")
print(dt2)

Оптимизация памяти

Выбор подходящих типов данных может значительно сократить использование памяти.

Выбор целочисленных типов

Пример

import pandas as pd
import numpy as np

# Создать Series с большим объёмом данных
s = pd.Series(np.random.randint(0, 100, 1000000))

# По умолчанию int64
print(f"Память int64: {s.dtype} -> {s.memory_usage(deep=True) / 1024 / 1024:.2f} MB")

# Преобразовать в меньший тип
s_int8 = s.astype("int8")
print(f"память int8: {s_int8.dtype} -> {s_int8.memory_usage(deep=True) / 1024 / 1024:.2f} MB")

# Выберите подходящий тип на основе диапазона данных
# np.iinfo для просмотра диапазона целых чисел
print(f"\n"диапазон int8: от {np.iinfo('int8').min} до {np.iinfo('int8').max}")
print(f"диапазон int16: от {np.iinfo('int16').min} до {np.iinfo('int16').max}")
print(f"диапазон int32: от {np.iinfo('int32').min} до {np.iinfo('int32').max}")

Использование типа category

Пример

import pandas as pd
import numpy as np

# Создайте Series с множеством повторяющихся значений
s = pd.Series(np.random.choice(["Пекин", "Шанхай", "Гуанчжоу", "Шэньчжэнь"], 1000000))

# Строковый тип
print(f"память типа object: {s.dtype} -> {s.memory_usage(deep=True) / 1024 / 1024:.2f} MB")

# Преобразовать в категориальный тип
s_cat = s.astype("category")
print(f"память типа category: {s_cat.dtype} -> {s_cat.memory_usage(deep=True) / 1024 / 1024:.2f} MB")

# Недостаток: некоторые операции могут замедлиться
print("\n"информация о category:")
print(s_cat.cat.categories)

Проверка типов и валидация

Пример

import pandas as pd
import numpy as np

df = pd.DataFrame({
    "Целое": [1, 2, 3],
    "Вещественное": [1.5, 2.5, 3.5],
    "Строка": ["a", "b", "c"]
})

# Проверить типы данных
print("Проверка, является ли это числовым типом:")
print(df.dtypes)

# Использовать is_integer_dtype
print(f"\n"Столбец Integer: {pd.api.types.is_integer_dtype(df['Integer'])}")
print(f"Столбец Float: {pd.api.types.is_float_dtype(df['Float'])}")
print(f"Столбец String: {pd.api.types.is_object_dtype(df['String'])}")

# Проверить, можно ли преобразовать в числовой тип
print(f"\n"Можно преобразовать в числовой тип: {pd.api.types.is_numeric_dtype(df['Integer'])}")
print(f"Является datetime: {pd.api.types.is_datetime64_any_dtype(pd.Series(pd.date_range('2024', periods=3)))}")

Распространённые проблемы

1. Значения float появляются в целочисленных столбцах

При смешивании в DataFrame он автоматически преобразуется в float64. ИспользуйтеNullable IntegerЭтот тип может сохранять целочисленные null-значения.

2. Несогласованные форматы дат

Используйтеpd.to_datetimeи укажитеformatпараметр для обработки нестандартных форматов.

3. Ошибка типа при чтении CSV

Используйтеdtypeпараметр, чтобы явно указать тип, или используйтеconvertersдля преобразования.

Для больших наборов данных отдавайте предпочтение использованию меньших типов данных (таких как int8, int16, float32) и категориальных типов, чтобы уменьшить использование памяти.

Другие расширения