如何在python中实现列表的四元组?

2024-10-02 22:35:33 发布

您现在位置:Python中文网/ 问答频道 /正文

我一直在研究应用一种称为“合并”的方法的概念,该方法将多个分布组合在一起。我在下面的链接中问了这个问题:How to implement Conflation for probability distribution in python?,这个问题用以下代码回答:

import scipy.stats as st
from scipy.integrate import quad
from scipy import stats
import numpy as np
from matplotlib import pyplot as plt

def prod_pdf(x,dists):
    p_pdf=1
    for dist in dists:
        print('Incoming Array:', dist.pdf(x))
        p_pdf=p_pdf*dist.pdf(x)
        print('final:', p_pdf)
    return print('Product: ', p_pdf), p_pdf
    
def product_pdf(x,dists):
    p_pdf=1
    for dist in dists:
        p_pdf=p_pdf*dist.pdf(x)
    return p_pdf

def conflate_pdf(x,dists,lb,ub):
    print('Input product pdf: ', prod_pdf(x,dists)[1])
    denom = quad(product_pdf, lb, ub, args=(dists,))[0]
    print('Denom: ', denom)
    conflated_pdf=product_pdf(x,dists)/denom
    print('Conflated PDF: ', conflated_pdf)
    return conflated_pdf

lb=-10
ub=10
domain=np.arange(lb,ub,.01)

dist_1 = st.norm.pdf(domain, 2,1)
dist_2 = st.norm.pdf(domain, 2.5,1.5)
dist_3 = st.norm.pdf(domain, 2.2,1.6)
dist_4 = st.norm.pdf(domain, 2.4,1.3)
dist_5 = st.norm.pdf(domain, 2.7,1.5)

plt.plot(domain, dist_1, 'r', label='Dist. 1')
plt.plot(domain, dist_2, 'g', label='Dist. 2')
plt.plot(domain, dist_3, 'b', label='Dist. 3')
plt.plot(domain, dist_4, 'y', label='Dist. 4')
plt.plot(domain, dist_5, 'c', label='Dist. 5')

dists=[stats.norm(2,1), stats.norm(2.5,1.5), stats.norm(2.2,1.6), stats.norm(2.4,1.3), stats.norm(2.7,1.5)]
graph=conflate_pdf(domain,dists,lb,ub)
plt.plot(domain,graph, 'm', label='Conflated Dist.')
plt.xlabel("domain")
plt.ylabel("pdf")
plt.title("Conflated PDF")
plt.legend()
plt.show()

我关注的区域是连续分布部分,它使用分母积分的方程。我知道代码中的错误是由于使用集成时出现了1个大小的数组错误。所以,我认为四元组的输入是使用一个整数,我试图修改代码以获得与上面代码相同的结果。代码如下所示:

import scipy.stats as st
from scipy.integrate import quad
from scipy import stats
import numpy as np
from matplotlib import pyplot as plt

def product_pdf(x,dists):
    p_list=[]
    p_pdf=1
    print('Incoming Array:', p_pdf)
    list_full_size=np.array(dists).shape
    print('list size: ', list_full_size[0])
    for x in range(list_full_size[1]):
        p_pdf=1
        for y in range(list_full_size[0]):
            p_pdf=p_pdf*dists[y][x]
            # print('Incoming Distribution Array:', dist)
            print('Product value: ', p_pdf)
        print('Product PDF:', p_pdf)
        p_list.append(p_pdf)
    print('final Product PDF:', p_pdf)
    print('Product PDF list: ', p_list)
    # return p_pdf
    return p_list
    # return np.array(p_list)

def conflate_pdf(x,dists,lb,ub):
    denom_list=[]
    # time.sleep(500)
    print('\n')
    print('product pdf: ', product_pdf(x,dists))
    prod=product_pdf(x,dists)
    prod_size=np.array(prod).shape[0]
    print('Product Size: ', prod_size)
    # time.sleep(20)
    for i in range(prod_size):
        denom = quad(product_pdf, lb, ub, args=(prod[i],))[0]
        denom_list.append(denom)
        print('Denom: ', denom)
    print('Denominator list: ', denom_list)
    # time.sleep(20)
    # conflated_pdf=prod_pdf(x,dists)/denom
    conflated_pdf=product_pdf(x,dists)/denom
    print('Conflated PDF: ', conflated_pdf)
    return conflated_pdf

lb=-10
ub=10
domain=np.arange(lb,ub,.01)

dist_1_pdf = st.norm.pdf(domain, 2,1)
dist_2_pdf = st.norm.pdf(domain, 4,2)
dist_3_pdf = st.norm.pdf(domain, 7,4)
dist_4_pdf = st.norm.pdf(domain, 2.4,1.3)
dist_5_pdf = st.norm.pdf(domain, 2.7,1.5)

# dist_1 = list(st.norm.pdf(domain, 2,1))
# dist_2 = list(st.norm.pdf(domain, 2.5,1.5))
# dist_3 = list(st.norm.pdf(domain, 2.2,1.6))
# dist_4 = list(st.norm.pdf(domain, 2.4,1.3))
# dist_5 = list(st.norm.pdf(domain, 2.7,1.5))

from matplotlib import pyplot as plt
plt.xlabel("domain")
plt.ylabel("pdf")
plt.title("Conflated PDF")
plt.plot(domain, dist_1_pdf, 'r', label='Dist. 1')
plt.plot(domain, dist_2_pdf, 'g', label='Dist. 2')
plt.plot(domain, dist_3_pdf, 'b', label='Dist. 3')
plt.plot(domain, dist_4_pdf, 'y', label='Dist. 4')
plt.plot(domain, dist_5_pdf, 'c', label='Dist. 5')

dist_1 = st.norm(2,1)
dist_2 = st.norm(4,2)
dist_3 = st.norm(7,4)
dist_4 = st.norm(2.4,1.3)
dist_5 = st.norm(2.7,1.5)

# dists=[dist_1, dist_2, dist_3, dist_4, dist_5]
dists=[dist_1_pdf, dist_2_pdf, dist_3_pdf, dist_4_pdf, dist_5_pdf]
graph=conflate_pdf(domain,dists,lb,ub)

plt.plot(domain,graph, 'm', label='Conflated PDF')
plt.legend()
plt.show()

当我运行代码时,我得到了以下输出:

print('list size: ', list_full_size[0])

IndexError: tuple index out of range

我知道错误与列表的大小有关,但是,如何修改代码以生成相同的结果并打印到第一个代码

编辑1:

我再次查看了代码并设法发现,如果我将quad替换为fixed_quad,它将能够无错误地运行代码。但是,绘图与user_conflation_pdf方法不同。这是我的方法代码

import scipy.stats as st
import numpy as np
import scipy.stats as st
import matplotlib.pyplot as plt
from sklearn.preprocessing import MinMaxScaler, Normalizer, normalize, StandardScaler
from scipy.integrate import quad, simps, quad_vec, nquad, cumulative_trapezoid
from scipy.integrate import romberg, trapezoid, simpson, romb
from scipy.integrate import fixed_quad, quadrature, quad_explain
from scipy import stats
import time

def user_prod_pdf(x,dists):
    p_list=[]
    p_pdf=1
    print('Incoming Array:', p_pdf)
    for dist in dists:
        print('Incoming Distribution Array:', dist.pdf(x))
        p_pdf=p_pdf*dist.pdf(x)
        print('Product PDF:', p_pdf)
        p_list.append(p_pdf)
    print('final Product PDF:', p_pdf)
    print('Product PDF list: ', p_list)
    return p_pdf

def user_conflate_pdf(x,dists,lb,ub):
    print('Input product pdf: ', user_prod_pdf(x,dists))
    denom = quad(user_prod_pdf, lb, ub, args=(dists,))[0]
    print('Denom: ', denom)
    conflated_pdf=user_prod_pdf(x,dists)/denom
    print('Conflated PDF: ', conflated_pdf)
    return conflated_pdf

def my_product_pdf(x,dists):
    p_list=[]
    p_pdf=1
    print('Incoming Array:', p_pdf)
    list_full_size=np.array(dists).shape
    print('Full list size: ', list_full_size)
    print('list size: ', list_full_size[0])
    for x in range(list_full_size[1]):
        p_pdf=1
        for y in range(list_full_size[0]):
            p_pdf=float(p_pdf)*dists[y][x]
            print('Product value: ', p_pdf)
        print('Product PDF:', p_pdf)
        p_list.append(p_pdf)
    print('final Product PDF:', p_pdf)
    print('Product PDF list: ', p_list)
    # return p_pdf
    return p_list
    # return np.array(p_list)
    
def my_conflate_pdf(x,dists,lb,ub):
    conflated_pdf_list=[]
    num=my_product_pdf(x,dists)
    print('\n')
    # print('product pdf: ', prod_pdf(x,dists))
    print('product pdf: ', my_product_pdf(x,dists))
    denom = fixed_quad(my_product_pdf, lb, ub, args=(dists,), n=1)[0]
    print('Denom: ', denom)
    # conflated_pdf=prod_pdf(x,dists)/denom
    # conflated_pdf=my_product_pdf(x,dists)/denom
    # conflated_pdf=[i / j for i,j in zip(my_product_pdf(x,dists), denom)]
    for i in np.arange(np.array(num).shape[0]):
        conflated_pdf = num[i] / denom
        conflated_pdf_list.append(conflated_pdf)
    print('Conflated PDF: ', conflated_pdf_list)
    return conflated_pdf_list

lb=-10
ub=10
domain=np.arange(lb,ub,.01)

# dist_1 = st.norm(2,1)
# dist_2 = st.norm(2.5,1.5)
# dist_3 = st.norm(2.2,1.6)
# dist_4 = st.norm(2.4,1.3)
# dist_5 = st.norm(2.7,1.5)

# dist_1_pdf = st.norm.pdf(domain, 2,1)
# dist_2_pdf = st.norm.pdf(domain, 2.5,1.5)
# dist_3_pdf = st.norm.pdf(domain, 2.2,1.6)
# dist_4_pdf = st.norm.pdf(domain, 2.4,1.3)
# dist_5_pdf = st.norm.pdf(domain, 2.7,1.5)

# dist_1_pdf /= dist_1_pdf.sum()
# dist_2_pdf /= dist_2_pdf.sum()
# dist_3_pdf /= dist_3_pdf.sum()
# dist_4_pdf /= dist_4_pdf.sum()
# dist_5_pdf /= dist_5_pdf.sum()

dist_1 = st.norm(2,1)
dist_2 = st.norm(4,2)
dist_3 = st.norm(7,4)
dist_4 = st.norm(2.4,1.3)
dist_5 = st.norm(2.7,1.5)

dist_1_pdf = st.norm.pdf(domain, 2,1)
dist_2_pdf = st.norm.pdf(domain, 4,2)
dist_3_pdf = st.norm.pdf(domain, 7,4)
dist_4_pdf = st.norm.pdf(domain, 2.4,1.3)
dist_5_pdf = st.norm.pdf(domain, 2.7,1.5)

# dist_1_pdf /= dist_1_pdf.sum()
# dist_2_pdf /= dist_2_pdf.sum()
# dist_3_pdf /= dist_3_pdf.sum()
# dist_4_pdf /= dist_4_pdf.sum()
# dist_5_pdf /= dist_5_pdf.sum()

# User:
plt.xlabel("domain")
plt.ylabel("pdf")
plt.title("User Conflated PDF")
plt.plot(domain, dist_1_pdf, 'r', label='Dist. 1')
plt.plot(domain, dist_2_pdf, 'g', label='Dist. 2')
plt.plot(domain, dist_3_pdf, 'b', label='Dist. 3')
plt.plot(domain, dist_4_pdf, 'y', label='Dist. 4')
plt.plot(domain, dist_5_pdf, 'c', label='Dist. 5')

dists=[dist_1, dist_2, dist_3, dist_4, dist_5]
user_graph=user_conflate_pdf(domain,dists,lb,ub)
print('Final Conflated PDF: ', user_graph)

# user_graph /= user_graph.sum()

plt.plot(domain, user_graph, 'm', label='Conflated PDF')
plt.legend()
plt.show()

# My Code:
# from matplotlib import pyplot as plt
plt.xlabel("domain")
plt.ylabel("pdf")
plt.title("My Conflated PDF Code")
plt.plot(domain, dist_1_pdf, 'r', label='Dist. 1')
plt.plot(domain, dist_2_pdf, 'g', label='Dist. 2')
plt.plot(domain, dist_3_pdf, 'b', label='Dist. 3')
plt.plot(domain, dist_4_pdf, 'y', label='Dist. 4')
plt.plot(domain, dist_5_pdf, 'c', label='Dist. 5')

dists=[dist_1_pdf, dist_2_pdf, dist_3_pdf, dist_4_pdf, dist_5_pdf]
my_graph=my_conflate_pdf(domain,dists,lb,ub)
print('Final Conflated PDF: ', my_graph)

# my_graph /= np.array(my_graph).sum()

# my_graph = inverse_normalise(my_graph)

plt.plot(domain, my_graph, 'm', label='Conflated PDF')
plt.legend()
plt.show()

# Conflated PDF:
print('User Conflated PDF: ', user_graph)
print('My Conflated PDF: ', my_graph)

以下是以下输出:

enter image description here

enter image description here

但是,如果我规范化pdf列表,输出图是相同的。以下是要使列表正常化需要更改的内容

user_graph /= user_graph.sum()
dist_1_pdf /= dist_1_pdf.sum()
dist_2_pdf /= dist_2_pdf.sum()
dist_3_pdf /= dist_3_pdf.sum()
dist_4_pdf /= dist_4_pdf.sum()
dist_5_pdf /= dist_5_pdf.sum()

输出:

enter image description here

enter image description here

如何修改代码/函数以获得此绘图

enter image description here


Tags: importnormpdfplotdomaindistpltlabel
1条回答
网友
1楼 · 发布于 2024-10-02 22:35:33

第一个大抱怨-你没有显示完整的回溯!到现在为止,您应该知道,检查回溯以准确了解问题的原因是非常重要的

从你所展示的一点,我推断问题在于:

def product_pdf(x,dists):
    p_list=[]
    p_pdf=1
    print('Incoming Array:', p_pdf)
    list_full_size=np.array(dists).shape
    print('list size: ', list_full_size[0])
    ...

你为什么不突出那个地方?阅读代码需要花费不必要的时间才能找到打印行

conflate_pdf(x,dists,lb,ub)中多次调用该函数。至少打印一次。那张照片有用吗?您的代码有一堆打印,但您没有显示其中任何一个:(

dists=[dist_1_pdf, dist_2_pdf, dist_3_pdf, dist_4_pdf, dist_5_pdf]
graph=conflate_pdf(domain,dists,lb,ub)

dists是一个由5个对象组成的列表。因此,我希望np.array(dists)至少是一个1d数组,如果那些pdf对象是具有相同形状的数组,可能会更多。这意味着list_full_size[0]应该工作,并且匹配len(dists)(即不需要将列表转换为数组)

这种array转换有助于

for x in range(list_full_size[1]):

虽然那也可以

for x in range(len(dists[0])):

因为xy循环从dists开始工作,而不是从np.array(dists)开始工作

无论如何,看起来product_pdf(x,dists)调用应该可以工作

但是,您也可以在中使用product_pdf

denom = quad(product_pdf, lb, ub, args=(prod[i],))[0]

那里的dists参数现在是prod[i],而不是原来的dists

什么是prod

prod=product_pdf(x,dists)

等等,product_pdf不是应该为quad生成一个数字吗?你在用prod[i]做什么,并把它作为dist参数传递给product_pdf

product_pdf返回plist,它看起来像一个数字列表。因此prod[i]是一个数字,它的形状作为数组是()。因此出现了错误。现在我们回到上次帮助您的错误-quad需要标量值函数。

相关问题 更多 >