Все материалы
AIгайдсредний

Нейросеть для Python: как писать и проверять код анализа

Как использовать нейросеть для Python и pandas: проверенный пример на 548 рейсах, пять ошибок с кодом до и после, тесты загрузки, merge, группировок и дат.

КейсПрактика25 сентября 2026 г.12 мин

Нейросеть быстро напишет pandas-код для выгрузки, но работа не заканчивается на строке print(total). Ошибка соединения может увеличить выручку, а пропуск в ключе — скрыть часть строк. Разбираем рабочий маршрут на таблице рейсов и пять проверок для кода модели.

Нейросеть для Python — короткий ответ

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

Рабочий цикл короткий: опишите файл и зерно таблицы, попросите минимальный код, запустите его, сравните число строк и сумму с известным итогом, затем добавьте преобразования по одному. Не передавайте модели только вопрос «сколько получилось?», если ответ пойдёт в отчёт.

Ниже пример на сохранённой таблице рейсов: 548 строк за 5 августа 2026 года, выручка 438 406 200 ₽ и медиана выручки рейса 209 750 ₽. Это не числа, которые модель «вспомнила»; они получены из файла и повторяются скриптом.

Что поручить ИИ и что проверить самому
ЭтапЧерновик от моделиКонтроль
Чтение файлаread_csv и типыshape и список колонок
Очисткаправила пропусковстроки до/после
Группировкаgroupbyсумма групп и общий итог
Соединениеmergeкардинальность ключей
Графиккод построенияисточник каждого числа

Что дать модели до просьбы написать код

Покажите схему: названия столбцов, типы, смысл строки и примеры значений. Если файл содержит рейсы, скажите, что revenue — выручка рейса, а status принимает Arrived и Cancelled. Уточните период, часовой пояс и какие строки должны войти в показатель. Иначе модель может выбрать свой фильтр и всё ещё вернуть синтаксически корректный код.

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

Попросите выводить проверки вместе с кодом: количество строк после чтения, отсутствие лишних колонок, типы чисел, общий итог до группировки. Такие строки превращают ошибку загрузки в явный сигнал, а не в незаметно изменившуюся выручку.

Пример: промпт для таблицы рейсов

В примере мы хотим узнать общую и медианную выручку рейса. Формулировка «посчитай выручку» оставляет неопределённым, считать ли только прибывшие рейсы. У сохранённого файла оба отменённых рейса имеют нулевую выручку; сумма от фильтра не изменится, а медиана потенциально может. Поэтому выбор статуса надо записать до запуска, а не оправдывать постфактум.

Модель должна вернуть код без заранее названной суммы: иначе она может подогнать ответ под подсказку. Эталон проверяется отдельно. Для повторяемости сохраните рядом файл, версию pandas и текст запроса. Это позволит объяснить изменение результата после обновления данных или правил.

codeПромпт для кодового помощника
Напиши Python 3 / pandas для файла day.csv.
Одна строка — рейс 5 августа 2026. Поля: flight_no, departure_airport, arrival_airport, dep_time, status, aircraft_code, passengers, revenue.
Посчитай число строк, сумму revenue и медиану revenue на всех строках.
Верни исполняемый код и проверки формы таблицы.
Не угадывай результат; если поле отсутствует — остановись.

Код, запуск и сверка с эталоном

Такой код можно запускать в обычном Python после установки pandas. Он не зависит от чата и не меняет исходный файл. Сначала проверяется набор колонок, затем тип выручки, затем итог. Явное приведение числа с ошибкой при неверном значении лучше молчаливого превращения мусора в ноль.

Мы запустили его на day.csv из собственного эксперимента: получили 548 строк, 438 406 200 ₽ и медиану 209 750 ₽. Контрольные assert специально оставлены в примере. При другой выгрузке их нужно заменить независимыми эталонами, а не подгонять константы под ответ модели.

Если сумма верна, проверьте ещё один срез: например, выручку по аэропорту вылета. Общий итог и сумма групп должны совпасть, если каждая строка принадлежит ровно одному аэропорту. Так легче заметить пропуски в ключе или неверное правило исключения.

pythonПроверенный код для day.csv
import pandas as pd
df = pd.read_csv('day.csv')
required = {'flight_no', 'departure_airport', 'revenue', 'status'}
assert required <= set(df.columns)
df['revenue'] = pd.to_numeric(df['revenue'], errors='raise')
rows = len(df)
total = int(df['revenue'].sum())
median = df['revenue'].median()
print(rows, total, median)
assert (rows, total, median) == (548, 438_406_200, 209_750)

Загрузка и чистка: не исправляйте данные наугад

Нейросеть охотно предложит dropna() или fillna(0) сразу после чтения CSV. Оба действия могут быть ошибкой. Пропущенный аэропорт и пропущенная выручка требуют разных решений: первый можно оставить отдельной категорией, вторую — отправить на разбор источника. Автоматическое заполнение нулём делает сумму ниже без видимого предупреждения.

Дайте модели правила по столбцам: какие обязательны, какие могут быть пустыми, как хранится дата, допустимы ли отрицательные значения. Попросите отчёт об изменениях: сколько строк исключено, какие поля преобразованы и как изменилась контрольная сумма. Исходный файл сохраните отдельно. Если код нельзя повторить с чистого состояния, исправление в ноутбуке не годится как производственный расчёт.

При чтении Excel или Parquet отдельно проверьте лист, типы и часовую зону. Само расширение файла ничего не говорит о семантике: одна и та же колонка может быть строкой в одном источнике и числом в другом.

Группировки и графики после проверки источника

Для отчёта по аэропортам нужен агрегат: groupby('departure_airport', dropna=False)['revenue'].sum(). dropna=False сохраняет строки без аэропорта отдельной группой. Если в вашей бизнес-логике они должны быть исключены, это решение нужно явно описать и показать их сумму отдельно.

График строится по уже проверенному агрегату. Модель может написать matplotlib-код, подобрать подписи и сортировку, но число столбцов и их высота должны прийти из той же таблицы, которая прошла контроль. Подпись «рост» имеет смысл лишь при сравнении периодов с одинаковой логикой; график за один день не доказывает тренд.

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

pythonГруппировка с сохранением пустых ключей
by_airport = df.groupby('departure_airport', dropna=False)['revenue'].sum()
assert int(by_airport.sum()) == total
print(by_airport.sort_values(ascending=False).head())

Ошибка 1. merge размножает строки

На рейс могут приходиться несколько билетов. Если присоединить таблицу билетов к рейсам и затем сложить поле revenue из рейсов, его значение повторится на каждой строке билета. Код выполняется и возвращает завышенную сумму — это особенно опасно для регулярного отчёта.

В демонстрации справа справочник аэропортов намеренно имеет повторяющийся ключ. Плохой merge увеличивает число строк. Правильный путь — решить, нужна ли связь многие ко многим, подготовить одну строку на ключ и включить validate='many_to_one'. Эта проверка остановит код при неожиданном дубле, вместо того чтобы дать правдоподобное число.

Перед каждым соединением спрашивайте: что одна строка слева, что одна строка справа и сколько совпадений ожидается? После соединения сравните число уникальных рейсов и сумму выручки с исходником.

pythonПлохо и лучше: проверка ключа при merge
airports = pd.DataFrame({'code': ['DME','DME'], 'city': ['Москва','Москва']})
# Плохо: каждый рейс из DME повторится дважды
bad = df.merge(airports, left_on='departure_airport', right_on='code')
# Лучше: уникальный справочник и явная кардинальность
unique_airports = airports.drop_duplicates('code')
good = df.merge(unique_airports, left_on='departure_airport', right_on='code', how='left', validate='many_to_one')
assert len(good) == len(df)
assert good['revenue'].sum() == df['revenue'].sum()

Ошибка 2. groupby молча теряет пустой ключ

По умолчанию groupby в pandas исключает группы с отсутствующим ключом. Если у части заказов не указан канал или у рейсов не заполнен аэропорт, сумма групп будет меньше общей суммы. ИИ может показать только красивую таблицу лидеров, не заметив потери.

В маленьком примере одна строка имеет пустой аэропорт и выручку 20. Плохой вариант возвращает только DME и сумму 10; правильный — сохраняет отдельную группу пустого ключа и сумму 30. В реальном отчёте пустые ключи нужно либо разбирать, либо явно исключать с указанием величины потери.

Не путайте dropna=False в группировке с заполнением всех пропусков строкой «неизвестно». Первое сохраняет исходное значение, второе изменяет данные. Выбор зависит от дальнейшего использования, но сверка суммы нужна в обоих случаях.

pythonПлохо и лучше: пропущенный ключ
sample = pd.DataFrame({'airport': ['DME', None], 'revenue': [10, 20]})
# Плохо: сумма групп равна 10, хотя в данных 30
bad = sample.groupby('airport')['revenue'].sum()
# Лучше: отдельная группа для пропуска
good = sample.groupby('airport', dropna=False)['revenue'].sum()
assert good.sum() == sample['revenue'].sum() == 30

Ошибка 3. даты хранятся как строки

Строки времени можно случайно сравнить лексикографически. Если формат неоднороден, «9:00» окажется позже «10:00» при строковом сравнении. Фильтр выполнится без ошибки и потеряет нужные записи. В исходном CSV dep_time содержит только время; календарную дату рейса мы знаем из определения выгрузки, а не из отдельного поля.

Правильный код сначала приводит строку к времени или полноценной дате, проверяет пропуски после парсинга, затем делает сравнение. Не стоит молча добавлять текущую дату компьютера — это изменит период при следующем запуске. Для данных с часовыми поясами нужно отдельно назвать исходную зону и зону отчёта.

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

pythonПлохо и лучше: тип времени
times = pd.Series(['9:00','10:00'])
# Плохо: строковый порядок не совпадает с временным
bad = times > '10:00'
# Лучше: парсинг с фиксированной датой и явной ошибкой
parsed = pd.to_datetime('2026-08-05 ' + times, format='%Y-%m-%d %H:%M', errors='raise')
good = parsed.dt.hour >= 10
assert bad.tolist() != good.tolist()

Ошибка 4. inplace и цепочка присваиваний

Код вида df[df['revenue'] > 0]['status'] = 'Arrived' выглядит как изменение таблицы, но обращение через две скобки создаёт неоднозначное присваивание. В актуальной модели Copy-on-Write pandas цепочка не обновляет исходный DataFrame. Аналитик потом смотрит на прежние значения и ошибочно считает, что очистка прошла.

Ещё одна ловушка — присвоить результат метода с inplace=True: многие такие методы возвращают None, и переменная перестаёт быть таблицей. Надёжнее явно присваивать результат операции и применять .loc для изменения строк. Если вы просите ИИ «почистить датафрейм», попросите его показать shape и значение контрольного поля до и после.

В примере ниже плохие строки оставлены комментариями: исполняемый вариант демонстрирует правильное обновление. Проверка утверждает, что исходный объект не меняется скрытым побочным эффектом.

pythonПлохо и лучше: явное присваивание
sample = pd.DataFrame({'revenue':[0,10], 'status':['Unknown','Unknown']})
# Плохо: sample[sample['revenue'] > 0]['status'] = 'Arrived'
# Плохо: sample = sample.dropna(inplace=True)  # результат None
# Лучше: явная цель изменения и отдельная переменная
sample.loc[sample['revenue'] > 0, 'status'] = 'Arrived'
clean = sample.dropna().copy()
assert clean.loc[1, 'status'] == 'Arrived'

Ошибка 5. apply вместо векторной операции

Для простого порога по выручке модель может предложить df.apply(lambda row: ..., axis=1). Такой код работает, но на больших таблицах лишний Python-вызов для каждой строки замедляет расчёт и усложняет поддержку. У pandas уже есть векторные сравнения, которые короче и легче проверять.

В примере обе версии дают одинаковые метки. Это и есть минимальный тест рефакторинга: сначала доказать совпадение, затем менять реализацию. Не надо обещать конкретный выигрыш в скорости без запуска бенчмарка на вашей версии библиотеки и вашем файле.

apply остаётся уместным, когда операция действительно не выражается штатными средствами. Ошибка не в самом методе, а в привычке генерировать построчный цикл для любой табличной задачи. Сначала ищите готовую колонную операцию.

pythonПлохо и лучше: векторизация
sample = pd.DataFrame({'revenue':[0, 10, 100]})
# Плохо для большого DataFrame: Python-функция на каждую строку
bad = sample.apply(lambda row: row['revenue'] > 0, axis=1)
# Лучше: операция над всей колонкой
good = sample['revenue'].gt(0)
assert bad.equals(good)

Как попросить нейросеть написать тесты

Тест «код запускается» слишком слаб. Попросите проверку инвариантов: сумма после группировки равна исходной, после связи многие к одному число строк не изменилось, пустые ключи учтены, дата корректно разобрана. Добавьте малые ручные примеры, где ожидаемый результат очевиден без модели.

Отделяйте тесты логики от тестов на конкретную выгрузку. Инвариант sum(groups) == sum(source) переносится между периодами при взаимно исключающих группах. Эталон 438 406 200 ₽ относится только к учебному CSV за один день. При обновлении файла он должен измениться по независимому источнику, а не автоматически подстраиваться под вывод программы.

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

Чат, Jupyter или редактор: где работать

Обычный чат подходит для вопроса о синтаксисе и черновика функции, если вы можете перенести код в свою среду и увидеть результат. Jupyter удобен для исследования по шагам: после каждой ячейки можно посмотреть DataFrame, но нужно следить за порядком выполнения и уметь запускать ноутбук заново с чистого состояния.

Редактор с кодовым помощником полезен, когда проект уже хранится в файлах: проще прочитать diff, запустить тесты и сохранить версию. Конкретные функции помощника, доступ к данным и способ выполнения меняются между продуктами; проверяйте документацию выбранного сервиса. Название интерфейса не решает вопрос доверия само по себе.

Для закрытых данных сначала выясните правила компании: допустимо ли отправлять схему, примеры строк или весь файл во внешний сервис. Часто достаточно синтетического примера, чтобы получить рабочий код, а настоящий файл запускать локально.

Четыре проверки перед отправкой результата

Первая — полнота: столько ли строк прочитано, сколько ожидалось? В эксперименте модель при переносе вставленного текста в код однажды потеряла 118 из 548 строк. При загрузке готового файла этот конкретный путь ошибки не возникал.

Вторая — смысл: правильное ли поле, период и правило статуса использованы? revenue рейса не равно сумме оплат по билету, если речь о другой метрике.

Третья — преобразования: не увеличилось ли зерно после merge, не исчезла ли категория из groupby, не обрезан ли временной интервал? Итоговая сумма без проверки промежуточных шагов может совпасть случайно.

Четвёртая — воспроизводимость: сохранены ли файл, код, версия окружения и вывод? Когда ассистент в чате меняет код между попытками, без файла трудно понять, какая версия дала число в отчёте.

Чек-лист работы с AI-кодом

Сформулируйте вопрос и определение метрики до промпта. Передайте схему и зерно, а не персональные строки. Попросите код с проверками. Запустите его на исходном файле и посмотрите первые строки, типы и shape. Сравните общую сумму и независимый эталон. После каждого merge проверьте ключи и размер. После каждой группировки — сохранность суммы. В конце сохраните код в проекте и повторите запуск с чистого состояния.

  • Схема, зерно и правила исключений записаны.
  • Файл прочитан целиком, типы проверены.
  • Число строк и контрольная сумма совпали.
  • Каждый merge проверен на кардинальность.
  • График использует тот же проверенный агрегат.

Частые вопросы

Может ли нейросеть написать Python без знания pandas? Да, но вам всё равно нужно понимать зерно таблицы, запускать код и проверять результат. Иначе нельзя отличить рабочий черновик от неверного отчёта.

Что лучше передать: CSV текстом или файлом? Для выполнения кода лучше файл: программа читает строки напрямую. В нашем эксперименте переписывание вставленного текста однажды привело к потере строк.

Почему код запускается, но сумма неверна? Возможны дубли после merge, исключённые группы с пропущенным ключом, неверный фильтр или неполный файл. Сравните размер и итог после каждого этапа.

Можно ли доверять тестам, которые написала сама модель? Они полезны, но могут повторять её неверное допущение. Добавьте независимый эталон и хотя бы один собственный пограничный пример.

Следующий шаг

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

Если хочется освоить сами табличные операции, изучите материалы по загрузке, очистке и группировке pandas. Нейросеть ускорит набор кода, а знание основных операций позволит заметить её ошибки до публикации цифры.

Продолжить чтение
Вся библиотека