← Назад к вопросам

Как происходит переход из одного типа данных в другой?

1.0 Junior🔥 82 комментариев
#Pandas и обработка данных#Python

Комментарии (2)

🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Типизация данных и кастинг (type casting) в ML контексте

Переход из одного типа данных в другой (type casting/conversion) — это процесс преобразования значения из одного типа в другой. В машинном обучении это критически важно, так как различные модели и алгоритмы требуют данные в определённых типах, а неправильный кастинг может привести к потере информации или ошибкам.

Основные типы данных в Python/NumPy

import numpy as np
import pandas as pd

# Целые числа
int8, int16, int32, int64      # от -128 до 127 ... до ±2^63
uint8, uint16, uint32, uint64  # от 0 до 255 ... до 2^64

# Числа с плавающей точкой
float16, float32, float64      # точность возрастает

# Категориальные
category                        # ограниченный набор значений
object                         # строки, смешанные типы

# Булевы
bool_                          # True/False

# Специальные
datetime64                     # временные метки
timedelta64                    # интервалы времени

Способы преобразования типов

1. Преобразование в числовые типы

import pandas as pd
import numpy as np

# Строка -> Float
df = pd.DataFrame({'price': ['100.5', '200.3', '150.0']})
df['price'] = df['price'].astype(float)
print(df['price'].dtype)  # float64

# String -> Int (осторожно с пропусками!)
df['quantity'] = pd.to_numeric(df['quantity'], errors='coerce')
print(df['quantity'].dtype)  # float64 (не int, так как может быть NaN)

# Явный int (если нет NaN)
df['id'] = df['id'].astype(np.int32)  # экономит память

2. Преобразование категориальных данных

# One-hot encoding (категории -> бинарные признаки)
df = pd.DataFrame({'color': ['red', 'blue', 'red', 'green']})
df_encoded = pd.get_dummies(df['color'], prefix='color')
print(df_encoded)
# color_blue  color_green  color_red
#      0            0           1
#      1            0           0
#      0            0           1
#      0            1           0

# Label encoding (категории -> числа)
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
df['color_encoded'] = le.fit_transform(df['color'])
# {'blue': 0, 'green': 1, 'red': 2}

# Категориальный тип Pandas
df['color'] = df['color'].astype('category')
print(df['color'].cat.codes)  # кодированные значения

3. Преобразование временных данных

# String -> Datetime
df['date'] = pd.to_datetime(df['date_string'])

# Извлечение признаков из datetime
df['year'] = df['date'].dt.year
df['month'] = df['date'].dt.month
df['day_of_week'] = df['date'].dt.dayofweek
df['hour'] = df['date'].dt.hour

# Преобразование в Unix timestamp
df['timestamp'] = df['date'].astype(np.int64) // 10**9  # секунды с 1970

4. Преобразование булевых значений

# String -> Bool
df['is_active'] = df['is_active'].astype(str).str.lower().isin(['true', '1', 'yes'])

# Number -> Bool
df['flag'] = df['flag'].astype(bool)  # 0 -> False, всё остальное -> True

# Bool -> Int (для моделей)
df['is_active_int'] = df['is_active'].astype(int)

Типизация в контексте ML моделей

Разные модели требуют разные типы

from sklearn.tree import DecisionTreeClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
import xgboost as xgb

df = pd.DataFrame({
    'numeric': [1.5, 2.3, 3.1],
    'category': ['A', 'B', 'A'],
    'bool': [True, False, True]
})

# 1. Decision Tree (может работать с категориальными)
tree = DecisionTreeClassifier()
tree.fit(df[['numeric']], df['bool'])

# 2. Logistic Regression (требует только числовые)
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
X = df[['numeric']].copy()
X['category_encoded'] = le.fit_transform(df['category'])
model = LogisticRegression()
model.fit(X, df['bool'])

# 3. XGBoost (работает с числовыми, категориальные нужно кодировать)
X_train = df[['numeric', 'bool']].astype(np.float32)  # экономит память
X_train['category_encoded'] = le.fit_transform(df['category'])
xgb_model = xgb.XGBClassifier()
xgb_model.fit(X_train, df['bool'])

Потенциальные проблемы при кастинге

1. Потеря точности

import numpy as np

# Float -> Int (потеря дробной части)
value = 3.99
int_value = int(value)  # 3, не 4!

# Правильное округление
import math
rounded = int(np.round(value))  # 4

# Float64 -> Float32 (потеря точности)
a = np.array([1.23456789123456789], dtype=np.float64)
b = a.astype(np.float32)
print(a[0], b[0])  # 1.2345678912... vs 1.23456788

2. Потеря информации с NaN

df = pd.DataFrame({'price': ['100', '200', 'invalid', '150']})

# Опасно: NaN станет 0 или вызовет ошибку
try:
    df['price'] = df['price'].astype(int)
except:
    print("Ошибка: невалидное значение")

# Правильно: используй coerce
df['price'] = pd.to_numeric(df['price'], errors='coerce')
print(df['price'])
# 0      100.0
# 1      200.0
# 2        NaN   <- заполнится NaN, затем нужно обработать
# 3      150.0

# Обработка NaN после кастинга
df['price'].fillna(df['price'].median(), inplace=True)

3. Переполнение памяти

# Плохо: каждая колонка float64 (8 байт)
df = pd.DataFrame({
    'small_int': np.random.randint(0, 100, 1000000),
    'small_float': np.random.rand(1000000)
})
print(df.memory_usage().sum() / 1e6)  # ~7.6 MB

# Хорошо: оптимизированные типы
df['small_int'] = df['small_int'].astype(np.uint8)  # 1 байт
df['small_float'] = df['small_float'].astype(np.float32)  # 4 байта
print(df.memory_usage().sum() / 1e6)  # ~2.4 MB (в 3 раза меньше!)

Практический пример: подготовка данных для ML

import pandas as pd
import numpy as np
from sklearn.preprocessing import StandardScaler

# Сырые данные
raw_data = pd.DataFrame({
    'user_id': ['1', '2', '3', '4'],
    'age': ['25', '30', 'unknown', '45'],
    'salary': ['50000.50', '60000.00', '75000.25', '80000'],
    'city': ['Moscow', 'SPB', 'Moscow', 'SPB'],
    'purchase_date': ['2023-01-15', '2023-02-20', '2023-03-10', '2023-04-05'],
    'is_premium': ['True', 'False', 'True', 'False']
})

# Этап 1: Типизация и очистка
data = raw_data.copy()
data['user_id'] = data['user_id'].astype(np.int32)
data['age'] = pd.to_numeric(data['age'], errors='coerce')
data['salary'] = pd.to_numeric(data['salary'], errors='coerce')
data['purchase_date'] = pd.to_datetime(data['purchase_date'])
data['is_premium'] = data['is_premium'].astype(str).str.lower() == 'true'

# Этап 2: Обработка пропусков
data['age'].fillna(data['age'].median(), inplace=True)
data['salary'].fillna(data['salary'].mean(), inplace=True)

# Этап 3: Кодирование категорий
data['city_encoded'] = pd.Categorical(data['city']).codes

# Этап 4: Извлечение признаков из datetime
data['days_since_purchase'] = (pd.Timestamp.now() - data['purchase_date']).dt.days

# Этап 5: Финальная типизация для модели
X = data[['user_id', 'age', 'salary', 'city_encoded', 'days_since_purchase']].astype(np.float32)
y = data['is_premium'].astype(int)

print(X.dtypes)
# user_id                   float32
# age                       float32
# salary                    float32
# city_encoded              float32
# days_since_purchase       float32

Лучшие практики

  1. Всегда проверяй типы после загрузки: df.dtypes, df.info()
  2. Используй pd.to_numeric() для безопасного преобразования: errors='coerce'
  3. Оптимизируй память: используй int8/int16 для небольших диапазонов
  4. Обработай пропуски до кастинга: NaN может помешать преобразованию
  5. Проверь результаты: убедись что конверсия сохранила смысл данных
  6. Документируй: какие типы требует твоя модель

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

Как происходит переход из одного типа данных в другой? | PrepBro