Генерация наборов данных: от случайных чисел до реалистичных структур

Раздел: Работа с данными -> Генерация данных

Основные подходы к генерации данных

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

Как быстро создать реалистичные тестовые данные?

Faker – библиотека для генерации фейковых данных, имитирующих реальные. Поддерживает множество локалей и типов данных: имена, адреса, тексты, даты, номера телефонов и другие.

from faker import Faker
fake = Faker('ru_RU')
print(fake.name())
print(fake.address())
print(fake.text(max_nb_chars=50))

Python создание данных (создание данных в python)

Иванова Елена Петровна
ул. Ленина, д. 10, кв. 5, Москва, 101000
Необходимо разработать новый подход к анализу данных.

Генерация выполняется за счёт предопределённых шаблонов. Можно задавать seed для воспроизводимости: Faker(seed=42).

Проблемы: не подходит для числовых распределений, требует установки (pip install faker). Ошибка: забывал указать локаль – по умолчанию английская. Решение: явно задавать локаль, например Faker('ru_RU').

Альтернативные способы

Как сгенерировать случайные числа или строки без внешних библиотек?

Модуль random предоставляет базовые функции для создания случайных значений.

import random
random.seed(10)
print(random.randint(1,100))
print(random.choice(['a','b','c']))
print(''.join(random.choices('abcdef', k=5)))
74
b
ffdbf

Ошибка: непонимание разницы между random.sample и random.choices. Первый без повторений, второй с повторениями. Также seed не всегда задаётся для всей программы.

Как получить массив случайных чисел с заданным распределением?

Библиотека numpy позволяет генерировать большие объёмы данных с различными распределениями.

import numpy as np
np.random.seed(0)
arr = np.random.normal(loc=0, scale=1, size=5)
print(arr)
[ 1.76405235  0.40015721  0.97873798  2.2408932   1.86755799]

Ошибка: путаница между старым и новым API (np.random.xxx vs np.random.default_rng()). Начиная с версии 1.17 рекомендуется использовать default_rng.

Как создать последовательность дат или случайную дату?

Модуль datetime в сочетании с random позволяет генерировать даты.

import random
from datetime import datetime, timedelta
start = datetime(2020,1,1)
end = datetime(2023,12,31)
delta = end - start
random_date = start + timedelta(days=random.randint(0, delta.days))
print(random_date.strftime('%Y-%m-%d'))
2021-07-14

Ошибка: не учтён часовой пояс или високосные годы – модуль datetime корректно обрабатывает, но при ручных расчётах возможны ошибки.

Как написать свой генератор данных с памятью состояния?

Функция-генератор с yield позволяет создавать бесконечные последовательности.

def id_generator(prefix='ID'):
    counter = 1
    while True:
        yield f"{prefix}_{counter:05d}"
        counter += 1
gen = id_generator()
for _ in range(3):
    print(next(gen))
ID_00001
ID_00002
ID_00003

Проблема: генератор бесконечен, требуется ограничение. Ошибка: забыл увеличить счётчик – приводит к бесконечному циклу с одинаковыми значениями.

Расширенные примеры

Генерация DataFrame для тестирования ML-моделей

Создан датасет с признаками: имя, возраст, зарплата, стаж.

Пример
import pandas as pd
from faker import Faker
import random
fake = Faker('ru_RU')
def generate_person():
    return {
        'name': fake.name(),
        'age': random.randint(20,60),
        'salary': round(random.uniform(30000,150000),2),
        'experience': random.randint(1,30)
    }
df = pd.DataFrame([generate_person() for _ in range(5)])
print(df)
                 name  age   salary  experience
0  Петров Иван Сергеевич   28  87345.80          14
1   Сидорова Анна Павловна   45  123456.78          22
2   Кузнецов Дмитрий Алексеевич   33  45678.90           5
3  Васильева Ольга Николаевна   52  98765.43          28
4  Николаев Максим Андреевич   39  65432.10          10

Пояснение: функция generate_person возвращает словарь, который затем собирается в DataFrame. Проблема: несоответствие типов или NaN – можно добавить проверки.

Создание временного ряда с шумом

Сгенерирована последовательность с линейным трендом и нормальным шумом.

Пример
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(42)
t = np.arange(0, 100, 0.1)
trend = 0.5*t
noise = np.random.normal(0, 10, size=len(t))
series = trend + noise
print(series[:10])
[  2.01597311   4.62261388   6.54192859   7.74262691   8.57443273
   9.93502617  11.86338901  13.05030749  13.86930945  15.16482598]

Пояснение: используется линейная функция с добавлением случайной составляющей. Ошибки: не задан seed – результаты невоспроизводимы.

Генерация набора строк с определённым форматом

Созданы пароли заданной длины из определённого алфавита.

Пример
import random
import string
alphabet = string.ascii_letters + string.digits
def generate_password(length=10):
    return ''.join(random.choice(alphabet) for _ in range(length))
for i in range(5):
    print(generate_password(12))
kL9pQ2wR8xVn
A1bC3dE5fG7h
sT4uV6wX8yZ0
mN2oP4qR6sT8
eW5rT7yU9iOp

Пояснение: алфавит собирается из букв и цифр. Проблема: пароль может не содержать специальные символы – можно расширить строкой punctuation.

Генерация списка словарей с разнородными полями

Созданы записи с полями разных типов: uuid, дата, категория.

Пример
import uuid
import random
from datetime import datetime, timedelta
def generate_record():
    return {
        'id': str(uuid.uuid4()),
        'date': (datetime.now() - timedelta(days=random.randint(0,365))).isoformat(),
        'category': random.choice(['A','B','C']),
        'value': random.random()
    }
records = [generate_record() for _ in range(3)]
for rec in records:
    print(rec)
{'id': '550e8400-e29b-41d4-a716-446655440000', 'date': '2024-06-15T12:34:56', 'category': 'B', 'value': 0.234567}
{'id': '6ba7b810-9dad-11d1-80b4-00c04fd430c8', 'date': '2024-03-01T09:00:00', 'category': 'A', 'value': 0.987654}
{'id': 'f47ac10b-58cc-4372-a567-0e02b2c3d479', 'date': '2024-12-25T23:59:59', 'category': 'C', 'value': 0.123456}

Пояснение: uuid генерирует уникальные идентификаторы, дата сдвигается на случайное число дней. Ошибка: isoformat может не соответствовать нужному формату – можно настроить strftime.

Создание данных в Python - comments

En
Python создание данных (python)