Итерация (или нет?) параметров для matplotlib для построения функции в Python

Подозреваю, что я до сих пор не совсем понимаю передачу аргументов (уже в моей предыдущей задаче: fmin (scipy) и понимание передачи параметров функции в Python)

Я придумал здесь упрощенную задачу и использовал итерацию, вдохновленный этим постом: Как использовать matplotlib для построения функции с аргументом на оси без использования другого n, потому что это не то, что мне нужно в моей функции.

import numpy as np
import matplotlib.pyplot as plt

%matplotlib inline

dataset=[0.2,0.5,0.02,0.4,0.7]

def functie_f(x,lamb_da):
    return lamb_da*np.power((lamb_da*x),2)
print (functie_f(0.2,7))


def LogL(q):
    lamb_da = q
    return np.log(functie_f(dataset, lamb_da)).sum()

lamb_da=2
 
y=[functie_f(dataset,lamb_da) for i in dataset]
plt.plot(dataset,y)
print(y)

print (LogL(lamb_da))
#y2=[LogL(lamb_da) for j in dataset]
#plt.plot(dataset,y2)

что дает мне такой результат:

Итерация (или нет?) параметров для matplotlib для построения функции в Python

Отпечаток y показывает, что у меня есть 5 раз один и тот же массив и 5 раз константная функция для каждого отдельного массива. Я ожидал увидеть 1 функцию. Я думаю, что произошло то, что functie_f обрабатывает один и тот же набор данных несколько раз, но без итерации он также дает неправильное количество значений y (вот почему я попробовал итерацию, чтобы дать мне значение y для каждого значения x из набора данных.

Когда мне нужен и второй график (= тот же код, но последние две строки не закомментированы), это еще хуже, и мой первый график исчез.

вы можете увидеть это на этом изображении:

Итерация (или нет?) параметров для matplotlib для построения функции в Python

Поэтому я попытался пропустить итерацию, так как это дает мне слишком много массивов с одинаковыми значениями y, но когда я это делаю, у меня нет одинакового измерения для значений x и значений y.

Что я не понимаю и хотел бы исправить:

  1. Почему я получаю больше значений y, когда начинаю с того же набора данных?
  2. Могу ли я использовать разные параметры для функции и как? (например, кортеж и одно значение)
  3. Правильно ли передается мой параметр для графика LogL, использующего functie_f?

Вот мои попытки без итерации с одной и той же ошибкой для трех разных кодов:

Сначала я попытался просто исключить итерацию для y:


y=functie_f(dataset,lamb_da)
plt.plot(dataset,y)

Затем я попытался перебрать x (думая, что на каждое 1 значение x потребуется 1 значение y)

for x in dataset
    y=functie_f(dataset,lamb_da)
    plt.plot(dataset,y)

И я попытался написать это под объявлением y, потому что, возможно, в его функции также есть набор данных x, но это ничего не изменило (я также попробовал «обновить ядро, чтобы заставить его перезапустить код»)

 y=functie_f(dataset,lamb_da)
 for x in dataset
     plt.plot(dataset,y)

Для всех трех изменений выше я получаю (то же самое) следующее сообщение об ошибке:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-4-347b473a5e13> in <module>
     19 y=functie_f(dataset,lamb_da)
     20 for x in dataset:
---> 21     plt.plot(dataset,y)
     22 print(y)
     23 

/home/marecage/snap/jupyter/common/lib/python3.7/site-packages/matplotlib/pyplot.py in plot(scalex, scaley, data, *args, **kwargs)
   2767     return gca().plot(
   2768         *args, scalex=scalex, scaley=scaley,
-> 2769         **({"data": data} if data is not None else {}), **kwargs)
   2770 
   2771 

/home/marecage/snap/jupyter/common/lib/python3.7/site-packages/matplotlib/axes/_axes.py in plot(self, scalex, scaley, data, *args, **kwargs)
   1633         """
   1634         kwargs = cbook.normalize_kwargs(kwargs, mlines.Line2D)
-> 1635         lines = [*self._get_lines(*args, data=data, **kwargs)]
   1636         for line in lines:
   1637             self.add_line(line)

/home/marecage/snap/jupyter/common/lib/python3.7/site-packages/matplotlib/axes/_base.py in __call__(self, data, *args, **kwargs)
    310                 this += args[0],
    311                 args = args[1:]
--> 312             yield from self._plot_args(this, kwargs)
    313 
    314     def get_next_color(self):

/home/marecage/snap/jupyter/common/lib/python3.7/site-packages/matplotlib/axes/_base.py in _plot_args(self, tup, kwargs, return_kwargs)
    496 
    497         if x.shape[0] != y.shape[0]:
--> 498             raise ValueError(f"x and y must have same first dimension, but "
    499                              f"have shapes {x.shape} and {y.shape}")
    500         if x.ndim > 2 or y.ndim > 2:

ValueError: x and y must have same first dimension, but have shapes (5,) and (10,)

Вам нужно что-то изменить между вызовами функций. Все, что вы делаете, это каждый раз вызываете функцию с одними и теми же параметрами. Предположительно, ваш data постоянен, а это означает, что что-то в lamb_da необходимо менять при каждом вызове, чтобы получать разные результаты от каждого вызова. Это как в математике: если у вас есть f(x) = x^2, вы спрашиваете, почему f(4) продолжает давать вам 16. Конечно, так и будет, вы каждый раз оцениваете функцию в 4.

jared 04.09.2024 14:06

Значит, x не взят из набора данных? Разве это не f(набор данных[0],лямбда), тогда f(набор данных[1], лямбда) , f(набор данных[2], лямбда), f(набор данных[3], лямбда),f(набор данных[4], лямбда) и готово!? То же самое и с y, почему он просматривает все наборы данных, а затем возвращается к ним 5 раз? если я скажу «i» в наборе данных, разве это не первое в наборе данных, второе в наборе данных, третье в наборе данных, четвертое в наборе данных, пятое в наборе данных, готово? Почему оно возвращается?

Sarawara 04.09.2024 14:25

Да и нет. for i in dataset действительно означает, что i сначала является первым элементом dataset, затем вторым и так далее. НО вы передаете не i в functie_f, а полный список dataset, для каждого значения i предполагается. И functie_f, очевидно, способен обрабатывать как отдельные значения, так и списки значений, косвенно отвечая на ваш второй вопрос.

Flow 04.09.2024 15:32

Вы передаете весь набор данных, но ваша последняя операция — суммировать значения, чтобы получить одно число. Кроме того, поскольку ваш набор данных представляет собой список, а не цифровой массив, lamb_da*x не делает того, что вы думаете.

jared 04.09.2024 15:55

Вывод: я отказываюсь от итерации (потому что не хочу передавать весь набор данных как значение)? Итак, я возвращаюсь к выражению: y=functie_f(dataset,lamb_da) plt.plot(dataset,y) без итерации, но тогда у меня появляется сообщение об ошибке, что у x и y нет одинакового измерения. Почему это? Потому что я никогда не указываю размерность y, кроме размера x, но когда он вызывается на графике, он имеет размерность в два раза больше x (см. Сообщения об ошибках, о которых идет речь)? Как мне этого избежать?

Sarawara 04.09.2024 17:05

@jared, он суммирует только функцию loglikelihood, functie_f не суммирует свои значения, поэтому нет причин считать его константой. Если я изменю свой набор данных на массив numpy, будет ли он принимать значения 1 на 1, а не весь набор?

Sarawara 04.09.2024 17:07

@Саравара, я неправильно понял твой код. Поскольку LogL не имеет значения, он не нужен в вашем вопросе.

jared 04.09.2024 19:12
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
7
53
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Когда dataset — обычный список Python, lamb_da*x — это список, умноженный на целое число, что просто дублирует список x раз. Например:

a = [1, 2, 3]
b = 2
c = a*b
print(c)  # [1, 2, 3, 1, 2, 3]

В этой строке вы также выполняете понимание списка:

y = [functie_f(dataset,lamb_da) for i in dataset]

Здесь вы каждый раз вызываете функцию одинаково, поэтому получаете len(dataset) одинаковые результаты.

Вы можете исправить это одним из двух способов.

  1. Вы можете сохранить понимание списка, но фактически перебирать набор данных.
import numpy as np
import matplotlib.pyplot as plt

def functie_f(x, lamb_da):
    return lamb_da*np.power((lamb_da*x), 2)

lamb_da = 2
dataset = [0.2, 0.5, 0.02, 0.4, 0.7]

y = [functie_f(x, lamb_da) for x in dataset]
plt.plot(dataset, y)

Ваша ошибка во всех ваших циклах заключалась в том, что вы создавали нужную вам переменную (в разных случаях вы называли ее i или x), но на самом деле не использовали эти значения.

  1. Вы можете преобразовать dataset в массив numpy и удалить понимание списка.
import numpy as np
import matplotlib.pyplot as plt

def functie_f(x,lamb_da):
    return lamb_da*np.power((lamb_da*x),2)

lamb_da = 2
dataset = np.array([0.2,0.5,0.02,0.4,0.7])
 
y = functie_f(dataset, lamb_da)
plt.plot(dataset, y)

Оба метода дают такой результат:

Примечание: линия выглядит так (идущая вперед и назад), потому что ваши значения dataset не отсортированы.

Другие вопросы по теме