Вопрос или проблема
У меня есть следующий DataFrame pandas, который представляет потребление за 7 дней (day_0
— это сегодня, day_-1
— это вчера и т.д.) 10 людей (ids
):
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randint(8, 15, size=(10, 7)))
df.columns = ['day_0', 'day_-1', 'day_-2', 'day_-3', 'day_-4', 'day_-5', 'day_-6']
df.index.name="id"
print(df.reset_index())
id day_0 day_-1 day_-2 day_-3 day_-4 day_-5 day_-6
0 0 10 10 14 8 14 14 14
1 1 10 13 11 11 8 10 10
2 2 10 12 9 12 9 10 10
3 3 12 12 9 11 9 12 13
4 4 12 13 8 12 8 11 9
5 5 13 9 8 13 9 12 10
6 6 8 9 8 14 8 13 14
7 7 13 10 14 12 8 9 11
8 8 8 8 10 12 11 14 14
9 9 14 13 13 9 11 14 13
Я хотел бы найти ежедневные веса (всего 7 весов: w_0, w_-1, w_-2, w_-3, w_-4, w_-5, w_-6
), которые должны иметь следующие свойства:
w_0
>w_-1
>w_-2
> … >w_-6
> 0w_0
+w_-1
+w_-2
+ … +w_-6
= 7- взвешенная средняя для точно
k
из 10ids
должна быть строго выше порога (например, 11)
Я могу удовлетворить условия 1 и 2, используя функцию экспоненциального затухания и затем нормализуя:
import numpy as np
n = 7
_lambda = 0.5
# Рассчитаем веса, используя экспоненциальное затухание
weights = np.exp(-_lambda * np.arange(n))
# Нормализуем веса так, чтобы их сумма равнялась длине временного ряда
weights *= n / np.sum(weights)
Но я не знаю, как я мог бы также применить условие 3.
Это возможно? Как я могу это сделать на python?
Ответ или решение
Для решения задачи оптимизации линейного программирования в Python с использованием библиотеки pandas
и дополнительной библиотеки для линейного программирования, такой как scipy.optimize
, нам необходимо учитывать три требования для весов:
- Веса должны быть строго положительными и убывающими.
- Сумма весов должна равняться 7.
- Взвешенное среднее должно превышать заданный порог для ровно
k
идентификаторов.
Шаги для решения задачи
-
Создание данных: Мы начнем с создания DataFrame с данными о потреблении.
-
Формулировка оптимизационной задачи: Мы определим переменные (веса) и ограничения для оптимизации.
-
Решение проблем с использованием
scipy.optimize
: Применим инструмент для решения заданной линейной задачи.
Пример кода
Здесь представлен подробный пример кода, который демонстрирует, как можно решать эту задачу:
import pandas as pd
import numpy as np
from scipy.optimize import linprog
# Шаг 1: Создание DataFrame с рандомными данными
np.random.seed(0)
df = pd.DataFrame(np.random.randint(8, 15, size=(10, 7)))
df.columns = ['day_0', 'day_-1', 'day_-2', 'day_-3', 'day_-4', 'day_-5', 'day_-6']
df.index.name = "id"
# Шаг 2: Определение переменных
n_days = 7
threshold = 11
k = 3 # Количество 'id', для которых среднее должно быть больше порога
# Оптимизационная задача
c = np.zeros(n_days) # Целевая функция (можно изменить по необходимости)
A_eq = np.ones((1, n_days)) # Сумма весов = 7
b_eq = [7]
# Границы для весов: w_i должно быть больше 0
bounds = [(0, None) for _ in range(n_days)]
# Шаг 3: Решение задачи с учетом весов
# Используем линейное программирование
opt_result = linprog(c, A_eq=A_eq, b_eq=b_eq, bounds=bounds, method='highs')
if opt_result.success:
weights = opt_result.x
print("Оптимальные веса:", weights)
# Шаг 4: Вычисление взвешенного среднего
weighted_averages = df.values @ weights
count_above_threshold = np.sum(weighted_averages > threshold)
if count_above_threshold == k:
print(f"Количество 'id' с взвешенными средними больше {threshold}: {count_above_threshold}")
else:
print(f"Не удается достичь ровно {k} 'id' с взвешенными средними больше {threshold}.")
else:
print("Не удалось найти оптимальные веса.")
Объяснение кода
-
Создание DataFrame: Мы создаем DataFrame с использованием случайных целых чисел для симуляции потребления.
-
Определение весов: Переменные для весов создаются, и мы определяем целевую функцию, в которой можно установливать различные условия.
-
Линейное программирование: Мы используем
linprog
изscipy.optimize
для нахождения весов. Указываем ограничения на сумму весов и границы. -
Вывод результатов: Проверяем, выполнены ли условия для количества идентификаторов, чьи взвешенные средние превышают заданный порог.
Заключение
Таким образом, этот подход демонстрирует, как можно использовать линейное программирование для нахождения оптимальных весов в условиях заданных ограничений. Вышеупомянутый код позволяет эффективно находить решения и адаптироваться к разным сценариям. Оптимизация может быть полезна в разных сферах, включая финансы, промышленные процессы и управление ресурсами.