December 29, 2023

Преобразование типов данных при загрузке данных из MS SQL в Pandas DataFrame и сохранение в Parquet

Pandas - мощная библиотека для анализа данных в языке программирования Python. Одной из её ключевых особенностей является работа с DataFrame, табличной структурой данных, которая предоставляет удобный интерфейс для манипуляций с данными. В этой статье мы рассмотрим, как произвести преобразование типов данных при загрузке данных из Microsoft SQL Server в Pandas DataFrame и как сохранить данные в формате Parquet с учетом корректных типов данных.

Шаг 1: Установка библиотек

Перед началом работы убедитесь, что у вас установлены необходимые библиотеки. Если их нет, установите их с помощью следующих команд:

pip install pandas
pip install pyodbc
pip install fastparquet

Шаг 2: Подключение к MS SQL и загрузка данных в Pandas DataFrame

Для начала подключимся к базе данных MS SQL Server с использованием библиотеки pyodbc:

import pandas as pd
import pyodbc

# Задайте свои параметры подключения
server = 'your_server'
database = 'your_database'
username = 'your_username'
password = 'your_password'

# Строка подключения
connection_string = f'DRIVER=ODBC Driver 17 for SQL Server;SERVER={server};DATABASE={database};UID={username};PWD={password}'

# Установка соединения
conn = pyodbc.connect(connection_string)

# SQL-запрос
sql_query = 'SELECT * FROM your_table'

# Загрузка данных в DataFrame
df = pd.read_sql(sql_query, conn)

Шаг 3: Преобразование типов данных

После загрузки данных из базы данных MS SQL в DataFrame необходимо убедиться, что типы данных корректны. Для этого воспользуемся методом astype():

# Преобразование типов данных
df['DatetimeColumn'] = pd.to_datetime(df['DatetimeColumn'], format='%Y-%m-%d %H:%M:%S', errors='coerce')
df['DateColumn'] = pd.to_datetime(df['DateColumn'], format='%Y-%m-%d', errors='coerce').dt.date
df['TimeColumn'] = pd.to_datetime(df['TimeColumn'], format='%H:%M:%S', errors='coerce').dt.time
df['IntColumn'] = df['IntColumn'].astype(int)
df['FlagColumn'] = df['FlagColumn'].astype(int)
df['FloatColumn'] = df['FloatColumn'].astype(float)

В приведенном выше коде DatetimeColumn, DateColumn и TimeColumn преобразуются в соответствующие типы данных даты и времени. IntColumn преобразуется в целое число, FlagColumn - в целое число 0 или 1, а FloatColumn - в число с плавающей точкой.

Шаг 4: Сохранение в формате Parquet

Теперь, когда типы данных корректны, можно сохранить данные в формате Parquet с использованием библиотеки fastparquet:

# Задайте путь к файлу Parquet
parquet_path = 'your_file.parquet'

# Сохранение в Parquet
df.to_parquet(parquet_path, index=False)

Теперь у вас есть DataFrame с корректными типами данных, загруженный из MS SQL Server, и сохраненный в формате Parquet.

Этот процесс обеспечивает правильное представление данных и сохраняет целостность типов при последующей загрузке данных в Pandas DataFrame.

Лучшие практики преобразования типов при загрузке данных в pandas

Преобразование типов данных при загрузке данных из CSV в DataFrame важно для обеспечения корректности анализа данных и оптимизации использования памяти. Ниже представлены лучшие практики для преобразования типов данных в Pandas DataFrame при чтении данных из CSV файлов:

Используйте параметр dtype при чтении данных:Параметр dtype позволяет явно указать тип данных для каждого столбца. Это может быть особенно полезно при загрузке больших данных, чтобы избежать автоматического определения типов, которое может быть медленным. Пример:

dtype_dict = {'column1': 'int32', 'column2': 'float64', 'column3': 'str'}
df = pd.read_csv('your_file.csv', dtype=dtype_dict)

Используйте параметр parse_dates для дат:

Если ваши данные содержат столбцы с датами, используйте параметр parse_dates для автоматического преобразования в объекты даты. Пример:

date_columns = ['date_column1', 'date_column2']
df = pd.read_csv('your_file.csv', parse_dates=date_columns)

Обрабатывайте пропущенные значения:

Используйте параметр na_values для указания значений, которые следует считать пропущенными. Это важно, чтобы Pandas правильно обрабатывал пропущенные значения и не превращал их в строки. Пример:

na_values = ['-1', 'NA', 'null']
df = pd.read_csv('your_file.csv', na_values=na_values)

Выбирайте наименьший подходящий тип данных:Выбирайте наименьший подходящий тип данных для каждого столбца, чтобы оптимизировать использование памяти. Например, если столбец содержит целые числа в ограниченном диапазоне, используйте int8 или int16, чтобы сэкономить память.

Оптимизируйте строковые столбцы:Если столбцы содержат ограниченное количество уникальных значений, рассмотрите возможность использования категориальных данных с помощью astype('category'). Это снижает потребление памяти и может ускорить операции с данными.

df['categorical_column'] = df['categorical_column'].astype('category')

Обрабатывайте большие файлы порциями:

При работе с большими CSV-файлами используйте параметр chunksize для чтения данных порциями. Это может быть полезно, если ваши ресурсы по памяти ограничены.

chunk_size = 10000
chunks = pd.read_csv('your_file.csv', chunksize=chunk_size)
for chunk in chunks:
    # Обработка каждой порции данных

Используйте память для чисел с плавающей точкой:

Если столбцы содержат числа с плавающей точкой, рассмотрите возможность использования float32 вместо float64. Это уменьшит потребление памяти в два раза.

df['float_column'] = df['float_column'].astype('float32')

Как обрабатывать отдельно пустые значения для строк, для int, для дат, datetime

При формировании DataFrame из разных типов столбцов в одной команде с использованием read_csv, можно применить более общий подход к обработке пустых значений для разных типов данных. Воспользуемся параметром converters для более гибкого управления преобразованием данных.

Пример:

import pandas as pd

# Задайте путь к вашему CSV файлу
csv_file_path = 'your_file.csv'

# Функция для обработки пустых значений для строк (str)
def process_string(value):
    return '' if value in ('', 'NA', 'null') else value

# Функция для обработки пустых значений для целых чисел (int)
def process_int(value):
    return pd.to_numeric(value, errors='coerce')

# Функция для обработки пустых значений для дат
def process_date(value):
    return pd.to_datetime(value, errors='coerce')

# Функция для обработки пустых значений для datetime
def process_datetime(value):
    return pd.to_datetime(value, errors='coerce')

# Задайте словарь с функциями-обработчиками для каждого столбца
column_processors = {
    'column1': process_string,
    'column2': process_string,
    'column3': process_int,
    'column4': process_int,
    'date_column1': process_date,
    'date_column2': process_date,
    'datetime_column1': process_datetime,
    'datetime_column2': process_datetime,
}

# Чтение CSV с применением обработчиков
df = pd.read_csv(csv_file_path, converters=column_processors)

В данном примере:

  • Создаются функции-обработчики (process_string, process_int, process_date, process_datetime), каждая из которых принимает значение и возвращает преобразованное значение, обрабатывая пустые значения по своему усмотрению.
  • Создается словарь column_processors, в котором каждому столбцу сопоставляется соответствующая функция-обработчик.
  • При чтении CSV используется параметр converters, который применяет соответствующий обработчик для каждого столбца.