Нейросеть для Python: как писать и проверять код анализа
Как использовать нейросеть для Python и pandas: проверенный пример на 548 рейсах, пять ошибок с кодом до и после, тесты загрузки, merge, группировок и дат.
Содержание статьи
Нейросеть быстро напишет pandas-код для выгрузки, но работа не заканчивается на строке print(total). Ошибка соединения может увеличить выручку, а пропуск в ключе — скрыть часть строк. Разбираем рабочий маршрут на таблице рейсов и пять проверок для кода модели.
Нейросеть для Python — короткий ответ
Нейросеть помогает писать Python для анализа данных: загрузить CSV, очистить типы, сгруппировать значения, соединить таблицы, построить график и подготовить тесты. Польза появляется после запуска кода. До этого перед вами лишь правдоподобный черновик, который может ссылаться на несуществующий столбец или молча терять строки.
Рабочий цикл короткий: опишите файл и зерно таблицы, попросите минимальный код, запустите его, сравните число строк и сумму с известным итогом, затем добавьте преобразования по одному. Не передавайте модели только вопрос «сколько получилось?», если ответ пойдёт в отчёт.
Ниже пример на сохранённой таблице рейсов: 548 строк за 5 августа 2026 года, выручка 438 406 200 ₽ и медиана выручки рейса 209 750 ₽. Это не числа, которые модель «вспомнила»; они получены из файла и повторяются скриптом.
| Этап | Черновик от модели | Контроль |
|---|---|---|
| Чтение файла | read_csv и типы | shape и список колонок |
| Очистка | правила пропусков | строки до/после |
| Группировка | groupby | сумма групп и общий итог |
| Соединение | merge | кардинальность ключей |
| График | код построения | источник каждого числа |
Что дать модели до просьбы написать код
Покажите схему: названия столбцов, типы, смысл строки и примеры значений. Если файл содержит рейсы, скажите, что revenue — выручка рейса, а status принимает Arrived и Cancelled. Уточните период, часовой пояс и какие строки должны войти в показатель. Иначе модель может выбрать свой фильтр и всё ещё вернуть синтаксически корректный код.
Для приватной таблицы достаточно обезличенного профиля и нескольких синтетических строк. Модель не обязана видеть всех клиентов, чтобы написать группировку. Но если она будет сама выполнять код, источник должен быть доступен среде исполнения: вложенный файл, разрешённое хранилище или локальный путь. Вставка всех строк в промпт менее надёжна, потому что при переписывании текста можно потерять часть таблицы.
Попросите выводить проверки вместе с кодом: количество строк после чтения, отсутствие лишних колонок, типы чисел, общий итог до группировки. Такие строки превращают ошибку загрузки в явный сигнал, а не в незаметно изменившуюся выручку.
Пример: промпт для таблицы рейсов
В примере мы хотим узнать общую и медианную выручку рейса. Формулировка «посчитай выручку» оставляет неопределённым, считать ли только прибывшие рейсы. У сохранённого файла оба отменённых рейса имеют нулевую выручку; сумма от фильтра не изменится, а медиана потенциально может. Поэтому выбор статуса надо записать до запуска, а не оправдывать постфактум.
Модель должна вернуть код без заранее названной суммы: иначе она может подогнать ответ под подсказку. Эталон проверяется отдельно. Для повторяемости сохраните рядом файл, версию pandas и текст запроса. Это позволит объяснить изменение результата после обновления данных или правил.
Напиши 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 специально оставлены в примере. При другой выгрузке их нужно заменить независимыми эталонами, а не подгонять константы под ответ модели.
Если сумма верна, проверьте ещё один срез: например, выручку по аэропорту вылета. Общий итог и сумма групп должны совпасть, если каждая строка принадлежит ровно одному аэропорту. Так легче заметить пропуски в ключе или неверное правило исключения.
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-код, подобрать подписи и сортировку, но число столбцов и их высота должны прийти из той же таблицы, которая прошла контроль. Подпись «рост» имеет смысл лишь при сравнении периодов с одинаковой логикой; график за один день не доказывает тренд.
Проверьте, что диаграмма не скрывает нулевые категории и не обрезает шкалу так, что различие кажется драматичнее. Отдельно укажите единицу измерения и период. Красивая визуализация без этих сведений усложняет, а не упрощает решение.
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'. Эта проверка остановит код при неожиданном дубле, вместо того чтобы дать правдоподобное число.
Перед каждым соединением спрашивайте: что одна строка слева, что одна строка справа и сколько совпадений ожидается? После соединения сравните число уникальных рейсов и сумму выручки с исходником.
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 в группировке с заполнением всех пропусков строкой «неизвестно». Первое сохраняет исходное значение, второе изменяет данные. Выбор зависит от дальнейшего использования, но сверка суммы нужна в обоих случаях.
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 содержит только время; календарную дату рейса мы знаем из определения выгрузки, а не из отдельного поля.
Правильный код сначала приводит строку к времени или полноценной дате, проверяет пропуски после парсинга, затем делает сравнение. Не стоит молча добавлять текущую дату компьютера — это изменит период при следующем запуске. Для данных с часовыми поясами нужно отдельно назвать исходную зону и зону отчёта.
После преобразования сравните количество валидных строк с исходным. Ошибочные значения времени должны стать видимыми в отчёте качества, а не исчезнуть из фильтра.
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 и значение контрольного поля до и после.
В примере ниже плохие строки оставлены комментариями: исполняемый вариант демонстрирует правильное обновление. Проверка утверждает, что исходный объект не меняется скрытым побочным эффектом.
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 остаётся уместным, когда операция действительно не выражается штатными средствами. Ошибка не в самом методе, а в привычке генерировать построчный цикл для любой табличной задачи. Сначала ищите готовую колонную операцию.
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. Нейросеть ускорит набор кода, а знание основных операций позволит заметить её ошибки до публикации цифры.
Материалы по теме

Pandas groupby и merge: как собрать аналитический отчёт из таблиц
Практический разбор groupby, merge и pivot_table в pandas: как агрегировать заказы, присоединять справочники и не посчитать выручку дважды.
Python и pandas на собеседовании: 20 задач для аналитика
Практический разбор задач по Python и pandas на собеседовании аналитика: фильтрация, groupby, merge, даты, пропуски, отладка и объяснение результата.

Нейросеть для анализа данных: эксперимент на 548 рейсах
Проверили четыре нейросети на таблице рейсов с известными ответами: ответ текстом, SQL и код на Python. Какая нейросеть лучше для анализа данных и как её проверить.