Обновлено 17 сентября 2026 года.
Python и R в Power BI подходят для специальных преобразований, статистики и графиков, которых нет среди обычных визуализаций. Чтобы выбрать правильный способ работы, сначала определите результат: нужна таблица для модели или изображение на странице отчёта. От этого зависят место запуска кода, обновление и ограничения.
Скрипт не делает расчёты автоматически точными, а публикация PBIX не переносит в облако локальную среду со всеми библиотеками. Ниже — единый маршрут: импорт шести строк из Python, расчёт с пропуском, графики на Python и R, проверка обновления в сервисе. Один набор данных используется во всех шагах.
В статье: выбор способа · настройка · импорт · расчёт · график Python · график R · обновление · ошибки.
Три способа использовать код
| Способ | Что получает код | Что получает Power BI | Когда меняется результат |
|---|---|---|---|
| Get data → Python script / R script | Данные, которые читает или создаёт скрипт | Таблицу DataFrame / data.frame | При выполнении запроса загрузки |
| Run Python script / Run R script в Power Query | Таблицу предыдущего шага как dataset | Преобразованную таблицу для модели | При обновлении запроса |
| Python visual / R visual | Выбранные поля в текущем контексте отчёта | Изображение графика | При обновлении данных и поддерживаемых взаимодействиях отчёта |
Если рассчитанная категория или прогноз должны участвовать в мерах DAX и других графиках, загрузите их как данные модели. Скрипт визуального элемента, который нарисовал картинку, не добавляет полученные значения в таблицы модели. Python в Power Query; R в Power Query.
Настройка локальной среды
- Установите нужный язык: Python из официального дистрибутива либо R. Для начала достаточно одного языка.
- Установите библиотеки в ту же среду, которую будет использовать Desktop. Для Python-примера ниже нужны pandas, NumPy и Matplotlib; для R-графика — ggplot2.
- В Desktop откройте File → Options and settings → Options. В глобальных настройках Python scripting или R scripting выберите установленную среду.
- Сначала выполните маленький скрипт загрузки и график, затем подключайте рабочие данные.
RStudio и Jupyter удобны для разработки, но не заменяют установленный runtime. Установка библиотеки в один Python и выбор другого в Power BI часто приводят к ModuleNotFoundError. Проверяйте путь и версии именно той среды, которая выполняет код. Настройка Python; Настройка R.
Импорт Python принимает pandas DataFrame, импорт R — data.frame. Скрипты загрузки, работающие дольше 30 минут, завершаются по тайм-ауту. Вызов, ожидающий ручного ввода, останавливает выполнение; для файлов используйте явные доступные пути. Это ограничения загрузки данных, а не лимиты визуального элемента.
Импорт Python: создайте DataFrame и загрузите таблицу
Этот шаг можно повторить без внешних файлов и доступа к рабочим данным. В Desktop выберите «Главная → Получить данные → Другие → Скрипт Python» и вставьте код. Названия команд зависят от языка и версии интерфейса.
import pandas as pd
sales = pd.DataFrame({
"RowID": [1, 2, 3, 4, 5, 6],
"Category": ["A", "A", "B", "B", "C", "C"],
"Quantity": [2.0, 2.0, 1.0, None, 3.0, 1.0],
"UnitPrice": [100.0, 100.0, 50.0, 80.0, 70.0, 0.0]
})
В навигаторе выберите DataFrame sales, откройте преобразование данных и назовите запрос Sales. Проверьте шесть строк, уникальные RowID от 1 до 6, текстовый Category и числовые Quantity и UnitPrice. В строке 4 количество должно остаться пустым. После этого можно выполнить Python-шаг из следующего раздела.
Python импортирует в Power BI именно pandas DataFrame. Список, картинка или результат print() сами по себе таблицей модели не становятся. При обновлении запрос снова выполняет скрипт: значения, введённые в коде, останутся учебными, пока вы не замените источник. Импорт Python по инструкции Microsoft.
Не смешивайте окна выполнения: в диалоге импорта скрипт создаёт sales, а в Power Query и visual входная таблица называется dataset. Ошибка «dataset не определён» часто означает, что код вставлен не в то окно. Если среда не находится или отсутствует пакет, сначала проверьте путь интерпретатора в настройках Desktop.
Учебные данные: почему нужен ключ строки
После импорта проверьте таблицу Sales по образцу ниже; если Python-импорт не нужен, такую же таблицу можно создать в Excel. RowID — уникальный номер строки продажи, Quantity и UnitPrice — числовые поля. Пустое Quantity в строке 4 означает неизвестное количество, а не ноль.
| RowID | Category | Quantity | UnitPrice | Ожидаемая Revenue |
|---|---|---|---|---|
| 1 | A | 2 | 100 | 200 |
| 2 | A | 2 | 100 | 200 |
| 3 | B | 1 | 50 | 50 |
| 4 | B | пропуск | 80 | не рассчитана |
| 5 | C | 3 | 70 | 210 |
| 6 | C | 1 | 0 | 0 |
Первые две строки совпадают по категории, количеству и цене, но это две разные продажи. Их нельзя удалять как дубли по этим трём полям. Нулевая цена в строке 6 — отдельный бизнес-вопрос: в примере она допустима, и строка не отбрасывается.
Python в Power Query: расчёт с явной обработкой пропуска
Откройте Transform data, выберите таблицу и запустите Transform → Run Python script. Предыдущий шаг будет доступен как dataset. Код оставляет все строки и помечает те, для которых можно рассчитать сумму:
import numpy as np
import pandas as pd
required = {"RowID", "Category", "Quantity", "UnitPrice"}
missing = required.difference(dataset.columns)
if missing:
raise ValueError("Missing columns: " + ", ".join(sorted(missing)))
clean = dataset.copy()
if clean["RowID"].isna().any() or clean["RowID"].duplicated().any():
raise ValueError("RowID must be present and unique")
for column in ["Quantity", "UnitPrice"]:
clean[column] = pd.to_numeric(clean[column], errors="coerce")
numbers = clean[["Quantity", "UnitPrice"]]
clean["IsValid"] = (
numbers.notna().all(axis=1)
& np.isfinite(numbers).all(axis=1)
& clean["Category"].notna()
)
clean["Revenue"] = (
clean["Quantity"] * clean["UnitPrice"]
).where(clean["IsValid"])
Выберите результирующий DataFrame clean и проверьте типы полей после возврата в Power Query. Получится шесть строк: пять с IsValid = true, одна — false. Revenue по известным значениям равна 660. Это известная сумма по пяти строкам, а не доказанная полная выручка по всем продажам: строку 4 ещё нужно исправить в источнике.
errors="coerce" переводит непарсящиеся значения в пропуски; код затем помечает их, а не скрывает заменой на ноль. Для денежных строк с запятыми, пробелами и символами валют сначала задайте явные правила разбора. Также отдельно определите правила возвратов, пустых категорий и диапазонов значений. Этот пример проверяет структуру и наличие конечных чисел, но не заменяет все бизнес-проверки. Документация pandas.to_numeric.
Python visual: график по подготовленным данным
Добавьте Python visual и поля RowID, Category, Revenue. Для числовых полей выберите «Не суммировать». RowID нужен даже тогда, когда его не будет на графике: без ключа Power BI может сгруппировать одинаковые строки до передачи в скрипт.
import matplotlib.pyplot as plt
import pandas as pd
data = dataset[["RowID", "Category", "Revenue"]].copy()
data["Revenue"] = pd.to_numeric(data["Revenue"], errors="coerce")
data = data.dropna(subset=["Category", "Revenue"])
totals = data.groupby("Category", sort=True)["Revenue"].sum()
fig, ax = plt.subplots(figsize=(7, 4))
if totals.empty:
ax.text(0.5, 0.5, "No valid rows", ha="center", va="center")
ax.set_axis_off()
else:
ax.bar(totals.index.astype(str), totals.values, color="#2367a5")
ax.set_xlabel("Category")
ax.set_ylabel("Known revenue")
ax.set_title("Revenue for rows with known values")
ax.spines[["top", "right"]].set_visible(False)
fig.tight_layout()
plt.show()
Без фильтров ожидаются A = 400, B = 50, C = 210. Выбор A в обычном срезе отчёта должен передать в скрипт соответствующий контекст и оставить столбец 400. Если не передать RowID, две строки A с Revenue = 200 могут превратиться в одну: тогда получится ошибочный итог 460 вместо 660.
Python visual показывает изображение. Оно реагирует на фильтры и подсветку от других элементов отчёта, но нажатие на нарисованный столбец не фильтрует остальные графики. Интерактивный HTML-виджет Plotly нельзя считать прямой заменой этого механизма. Устройство Python visual.
Тот же график на R
В R visual передайте те же RowID, Category, Revenue с сохранением детализации. Revenue должна иметь числовой тип в модели. Используем ggplot2 и уже рассчитанные суммы, а не количество записей:
library(ggplot2)
data <- dataset[!is.na(dataset$Category) & !is.na(dataset$Revenue), ]
if (nrow(data) == 0) {
plot.new()
text(0.5, 0.5, "No valid rows")
} else {
totals <- aggregate(Revenue ~ Category, data = data, FUN = sum)
p <- ggplot(totals, aes(x = Category, y = Revenue)) +
geom_col(fill = "#2367a5") +
labs(x = "Category", y = "Known revenue",
title = "Revenue for rows with known values") +
theme_minimal()
print(p)
}
geom_col() использует переданные значения высот. Обычный geom_bar() без изменения статистики считает записи, что дало бы другой показатель. Результаты должны совпасть с Python: 400, 50 и 210. Различие geom_col и geom_bar.
R visual также получает сгруппированные поля и возвращает изображение. Его можно обновлять фильтрами отчёта, но нельзя использовать клики внутри картинки как обычный перекрёстный фильтр других визуализаций. Создание R visual в Desktop.
Лимиты Desktop и Power BI service
| Сценарий | Ограничение | Практический вывод |
|---|---|---|
| Python visual в Desktop | До 150 000 строк, до 250 МБ входных данных, до 5 минут вычисления | Не передавайте в график весь массив событий без ограничения |
| R visual в Desktop | До 150 000 строк, до 5 минут вычисления; изображение до 2 МБ | Контролируйте детализацию и размер результата |
| Python visual в сервисе | До 30 МБ суммарного сжатого входного пакета и скрипта, до 1 минуты | Успех локального выполнения не гарантирует успех публикации |
| R visual в сервисе | До 150 000 строк, до 250 МБ входа, до 60 секунд вычисления | Проверяйте время на облачной среде |
Ограничения приведены по текущей документации: Python Desktop, R Desktop, Python service, R service. Предупреждение об усечении строк означает неполный набор для расчёта, а не безобидное ограничение внешнего вида.
Пакеты и доступ к сети после публикации
Облачная среда визуализаций имеет собственные версии Python/R и список поддерживаемых пакетов. Локальная команда установки не добавляет библиотеку в сервис. Проверяйте не только имя пакета, но и версию и зависимости. Для Python-визуализаций сетевые клиент-серверные запросы в сервисе блокируются; нельзя рассчитывать, что код внутри графика скачает модель или запросит внешний API. Пакеты и ограничения Python; Поддержка пакетов R.
Если нужен закрытый пакет, собственная модель или внешний API, выполните расчёт в управляемом процессе подготовки данных и загрузите результат в Power BI. Разделите получение данных и их показ: это упрощает повторный запуск, журналирование и проверку версии модели.
Как обновлять модель со скриптом Power Query
Для обновления опубликованной модели с R/Python-шагами Power Query используется on-premises data gateway в personal mode. На его компьютере должны быть совместимая среда и пакеты, а компьютер и шлюз должны оставаться доступными во время обновления. Это отличается от облачного выполнения скрипта визуализации при просмотре отчёта. Personal gateway и скрипты.
У этого подхода есть ограничение конфиденциальности: документация шагов R/Python в Power Query требует уровня Public для задействованных источников. Он управляет изоляцией данных при объединении запросов и не равен команде публикации отчёта в интернете. Однако назначать его конфиденциальным источникам только ради устранения ошибки неправильно. Если требования к изоляции несовместимы с таким режимом, перенесите преобразование за пределы Power Query. Ограничения Python-шагов; Смысл privacy levels.
Для командного процесса с требованиями к отказоустойчивости оцените выполнение R/Python в отдельном задании, например notebook или ETL-процессе, с записью результата в базу или lakehouse. Personal gateway привязан к одному пользователю и не предоставляет кластер высокой доступности. Рекомендации Microsoft по выбору шлюза.
Статистика и машинное обучение: что проверять
Не обучайте сложную модель заново при каждом изменении среза только потому, что visual позволяет выполнить код. Пользовательский фильтр может поменять обучающую выборку, а ограничение количества строк — незаметно обрезать её. Для рабочего прогноза обычно нужны отдельно подготовленная модель, версия обучения, дата расчёта и сохранённые прогнозы.
- Отделяйте обучающие данные от проверки. Заполнение пропусков, масштабирование и отбор признаков должны обучаться на тренировочной части.
- Для временного прогноза проверяйте результат на более поздних периодах и сравнивайте с простым базовым прогнозом.
- Не считайте корреляцию доказательством причинного эффекта.
- Не удаляйте выбросы автоматически: крупная продажа может быть настоящей, а возврат — законной операцией.
- Разделяйте измеренное значение, оценку модели и пропуск; показывайте дату и область применимости расчёта.
Утечка данных при подготовке признаков способна сделать качество на проверке завышенным. Используйте воспроизводимый конвейер обработки и одинаковые преобразования при обучении и применении модели. Разбор ошибок подготовки данных в scikit-learn.
Если результат не совпал: найдите слой ошибки
| Симптом | Что проверить | Контрольный результат |
|---|---|---|
| ModuleNotFoundError | Путь к Python в Desktop и установка пакета в этой среде | Импорт создаёт таблицу sales из 6 строк |
| dataset не определён | Окно запуска: импорт, шаг Power Query или visual | На входе преобразования доступны 4 исходных столбца |
| Сумма A равна 200 вместо 400 | Не потеряны ли одинаковые продажи; передан ли RowID в visual | Две разные строки A дают 400 |
| Вместо пропуска получился ноль | Правила приведения типов и замены пустых значений | Строка 4 остаётся IsValid = false и без Revenue |
| Desktop работает, сервис — нет | Для загрузки — шлюз и локальная среда; для visual — пакеты, лимиты, права и доступность региона | Отдельно проходят обновление модели и показ графика |
Для источника, где любое нечисловое значение должно останавливать загрузку, используйте pd.to_numeric(..., errors="raise"). В нашем практикуме выбран другой явный режим: сохранить строку и пометить проблему. Не заменяйте одно поведение другим без решения о том, как пользователь узнает о неполных данных.
Проверка перед передачей отчёта
- Сравните количество входных строк и контрольную сумму с источником. Для примера: 6 строк, 1 пропуск, известная сумма 660.
- Проверьте отсутствие непреднамеренного объединения одинаковых продаж; сохраните ключ строки в полях visual.
- Проверьте пустой фильтр, одну категорию, некорректное число и отсутствующий столбец.
- Запустите обновление в сервисе и откройте отчёт под обычным пользователем; проверьте пакеты, время и права.
- Храните исходные скрипты, зависимости и контрольные данные вместе с версией отчёта. Не обещайте, что один PBIX автоматически решит слияние изменений нескольких разработчиков.
- Зафиксируйте владельца процесса, расписание и порядок реакции на ошибку. Старый успешный результат не должен выглядеть как новый расчёт.
При ошибке сначала выясните, какой слой её выдал: загрузка Power Query, Python/R runtime, облачный visual или шлюз. Затем воспроизведите её на небольшом наборе с теми же типами и версиями. Так исправление будет связано с конкретной причиной, а не со случайным обновлением всех библиотек.