【问题标题】:How to fix error regarding size-1 arrays?如何修复有关 size-1 数组的错误?
【发布时间】:2021-03-12 17:16:29
【问题描述】:

我正在研究一个问题,即使用一种名为 Conflation 的方法中的方程将几个连续概率分布组合成一个连续概率分布(可以在以下链接中找到 Conflation 方程:Conflation method question)。当我运行代码时,我收到有关 size-1 数组的错误消息。这是我的错误消息代码:

错误信息:

Traceback (most recent call last):
  File "/tmp/sessions/c903d99d60f20c3b/main.py", line 72, in <module>
    graph=conflate_pdf(domain, dists,lb,ub)
  File "/tmp/sessions/c903d99d60f20c3b/main.py", line 58, in conflate_pdf
    denom = quad(prod_pdf, lb, ub, args=(dists))[0]
  File "/usr/local/lib/python3.6/dist-packages/scipy/integrate/quadpack.py", line 341, in quad
    points)
  File "/usr/local/lib/python3.6/dist-packages/scipy/integrate/quadpack.py", line 448, in _quad
    return _quadpack._qagse(func,a,b,args,full_output,epsabs,epsrel,limit)
TypeError: only size-1 arrays can be converted to Python scalars

代码:

def prod_pdf(x,pdfs):
    prod=np.ones(pdfs[0].shape[0])
    for pdf in pdfs:
        prod=prod*pdf
    return prod

def conflate_pdf(x,dists,lb,ub):
    denom = quad(prod_pdf, lb, ub, args=(dists))[0]
    return prod_pdf(x,dists)/denom

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

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

dists=[dist_1, dist_2, dist_3, dist_4, dist_5]
graph=conflate_pdf(domain, dists,lb,ub)

from matplotlib import pyplot as plt
plt.plot(domain, dist_1)
plt.plot(domain, dist_2)
plt.plot(domain, dist_3)
plt.plot(domain, dist_4)
plt.plot(domain, dist_5)
plt.plot(domain,graph)
plt.xlabel("domain")
plt.ylabel("pdf")
plt.title("Conflated PDF")
plt.show()

从代码来看,这个错误信息是什么原因造成的?

编辑 1:

我修改了代码并进行了一些更正,但我仍然不断收到相同的错误消息。请参阅下面的代码和代码中的错误消息:

代码:

def prod_pdf(x,dists):
    prod=np.ones(np.array(dists)[0].shape)
    for dist in dists:
        print(prod)
        for c,y in enumerate(dist):
            prod[c]=prod[c]*y
        print('final:', prod)
    return prod

def conflate_pdf(x,dists,lb,ub):
    denom = quad(prod_pdf, lb, ub, dists)[0]
    # denom = simps(prod_pdf)
    print('Denom: ', denom)
    print('product pdf: ', prod_pdf(x,dists))
    conflated_pdf=prod_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)

from matplotlib import pyplot as plt
plt.plot(domain, dist_1, 'r')
plt.plot(domain, dist_2, 'g')
plt.plot(domain, dist_3, 'b')
plt.plot(domain, dist_4, 'y')
plt.plot(domain, dist_5, 'c')

dists=[dist_1, dist_2, dist_3, dist_4, dist_5]
graph=conflate_pdf(domain, dists,lb,ub)

plt.plot(domain,graph, 'm')
plt.xlabel("domain")
plt.ylabel("pdf")
plt.title("Conflated PDF")
plt.show()

回溯消息位置:

第 341 行:

if weight is None:
    retval = _quad(func, a, b, args, full_output, epsabs, epsrel, limit,points)

第 448 行:

def _quad(func,a,b,args,full_output,epsabs,epsrel,limit,points):
    infbounds = 0
    if (b != Inf and a != -Inf):
        pass   # standard integration
    elif (b == Inf and a != -Inf):
        infbounds = 1
        bound = a
    elif (b == Inf and a == -Inf):
        infbounds = 2
        bound = 0     # ignored
    elif (b != Inf and a == -Inf):
        infbounds = -1
        bound = b
    else:
        raise RuntimeError("Infinity comparisons don't work for you.")

    if points is None:
        if infbounds == 0:
            return _quadpack._qagse(func,a,b,args,full_output,epsabs,epsrel,limit)
        else:
            return _quadpack._qagie(func,bound,infbounds,args,full_output,epsabs,epsrel,limit)
    else:
        if infbounds != 0:
            raise ValueError("Infinity inputs cannot be used with break points.")
        else:
            #Duplicates force function evaluation at singular points
            the_points = numpy.unique(points)
            the_points = the_points[a < the_points]
            the_points = the_points[the_points < b]
            the_points = numpy.concatenate((the_points, (0., 0.)))
            return _quadpack._qagpe(func,a,b,the_points,args,full_output,epsabs,epsrel,limit)

编辑 2:

@hpaulj 讨论后,似乎问题出在产品功能上。从链接Conflation method question 中,代码能够运行而不会出现 size-1 数组的错误。这是包含更多详细信息的代码:

代码:

from scipy.integrate import quad
from scipy import stats
import numpy as np

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

def conflate_pdf(x,dists,lb,ub):
    print('Input product pdf: ', prod_pdf(x,dists))
    denom = quad(prod_pdf, lb, ub, args=(dists,))[0]
    print('Denom: ', denom)
    conflated_pdf=prod_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)
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)]

from matplotlib import pyplot as plt
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')

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()

这是输出的一小部分:

Incoming Array: 1
final: 0.15352177537004433
final: 0.034348669264845304
final: 0.006519131844904635
final: 0.0015040030811035296
final: 0.0003607258742065213
Incoming Array: 1
final: 0.042345986284209325
final: 0.006294747321619583
final: 0.0007651214249593444
final: 9.805307029794648e-05
final: 1.668121592516301e-05
Denom:  0.0029066671327537714
Incoming Array: 1
final: [2.14638374e-32 2.41991991e-32 2.72804284e-32 ... 6.41980576e-15
 5.92770938e-15 5.47278628e-15]
final: [4.75178372e-48 5.66328097e-48 6.74864868e-48 ... 7.03075979e-21
 6.27970218e-21 5.60806584e-21]
final: [2.80912097e-61 3.51131870e-61 4.38823989e-61 ... 1.32670185e-26
 1.14952951e-26 9.95834610e-27]
final: [1.51005552e-81 2.03116529e-81 2.73144352e-81 ... 1.76466623e-34
 1.46198598e-34 1.21092834e-34]
final: [1.09076800e-97 1.55234627e-97 2.20861552e-97 ... 3.72095218e-40
 2.98464396e-40 2.39335035e-40]
Conflated PDF:  [3.75264162e-95 5.34063998e-95 7.59844666e-95 ... 1.28014389e-37
 1.02682689e-37 8.23400219e-38]

剧情:

在我看来,它从一个中获取每个密度值并将其与其他分布相乘。但是,如果我看一下我的情况,它不是获取一个变量,而是在乘积函数之后获取整个数组,并且它对 size-1 数组产生相同的错误。请参阅以下代码和部分输出:

代码:

from scipy.integrate import quad
from scipy import stats
import numpy as np

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

def conflate_pdf(x,dists,lb,ub):
    print('Input product pdf: ', prod_pdf(x,dists))
    denom = quad(prod_pdf, lb, ub, args=(dists,))[0]
    # denom = simps(prod_pdf)
    # denom = nquad(func=(prod_pdf), ranges=([lb, ub]), args=(dists,))[0]
    print('Denom: ', denom)
    conflated_pdf=prod_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)

from matplotlib import pyplot as plt
plt.xlabel("domain")
plt.ylabel("pdf")
plt.title("Conflated PDF")
plt.legend()
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=[dist_1, dist_2, dist_3, dist_4, dist_5]
print('distribution list: \n', dists)
graph=conflate_pdf(domain, dists,lb,ub)

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

这是输出的一小部分:

Incoming Array: 1
final: [2.14638374e-32 2.41991991e-32 2.72804284e-32 ... 6.41980576e-15
 5.92770938e-15 5.47278628e-15]
final: [4.75178372e-48 5.66328097e-48 6.74864868e-48 ... 7.03075979e-21
 6.27970218e-21 5.60806584e-21]
final: [2.80912097e-61 3.51131870e-61 4.38823989e-61 ... 1.32670185e-26
 1.14952951e-26 9.95834610e-27]
final: [1.51005552e-81 2.03116529e-81 2.73144352e-81 ... 1.76466623e-34
 1.46198598e-34 1.21092834e-34]
final: [1.09076800e-97 1.55234627e-97 2.20861552e-97 ... 3.72095218e-40
 2.98464396e-40 2.39335035e-40]
Input product pdf:  [1.09076800e-97 1.55234627e-97 2.20861552e-97 ... 3.72095218e-40
 2.98464396e-40 2.39335035e-40]
Incoming Array: 1
final: [2.14638374e-32 2.41991991e-32 2.72804284e-32 ... 6.41980576e-15
 5.92770938e-15 5.47278628e-15]
final: [4.75178372e-48 5.66328097e-48 6.74864868e-48 ... 7.03075979e-21
 6.27970218e-21 5.60806584e-21]
final: [2.80912097e-61 3.51131870e-61 4.38823989e-61 ... 1.32670185e-26
 1.14952951e-26 9.95834610e-27]
final: [1.51005552e-81 2.03116529e-81 2.73144352e-81 ... 1.76466623e-34
 1.46198598e-34 1.21092834e-34]
final: [1.09076800e-97 1.55234627e-97 2.20861552e-97 ... 3.72095218e-40
 2.98464396e-40 2.39335035e-40]

编辑 3:

我设法查看代码以在 Edit 2 中实现相同的方法,但我编辑了从每个发行版中获取第一个变量的代码,但对于循环的其余部分继续打印相同的值,它不会转到列表中的下一个值,并且混合分布是单个变量。请参阅以下代码和部分输出:

代码:

from scipy.integrate import quad
from scipy import stats
import numpy as np

def prod_pdf(x,dists):
    p_pdf=1
    print('Incoming Array:', p_pdf)
    for c,dist in enumerate(dists):
        p_pdf=p_pdf*dist[c]
        print('final:', p_pdf)
    return p_pdf

def conflate_pdf(x,dists,lb,ub):
    print('Input product pdf: ', prod_pdf(x,dists))
    denom = quad(prod_pdf, lb, ub, args=(dists,))[0]
    # denom = simps(prod_pdf)
    # denom = nquad(func=(prod_pdf), ranges=([lb, ub]), args=(dists,))[0]
    print('Denom: ', denom)
    conflated_pdf=prod_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)

from matplotlib import pyplot as plt
plt.xlabel("domain")
plt.ylabel("pdf")
plt.title("Conflated PDF")
plt.legend()
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=[dist_1, dist_2, dist_3, dist_4, dist_5]
print('distribution list: \n', dists)
graph=conflate_pdf(domain, dists,lb,ub)

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

部分输出:

Incoming Array: 1
final: 2.1463837356630605e-32
final: 5.0231307782193034e-48
final: 3.266239495519432e-61
final: 2.187514996217005e-81
final: 1.979657878680375e-97
Incoming Array: 1
final: 2.1463837356630605e-32
final: 5.0231307782193034e-48
final: 3.266239495519432e-61
final: 2.187514996217005e-81
final: 1.979657878680375e-97
Denom:  3.95931575736075e-96
Incoming Array: 1
final: 2.1463837356630605e-32
final: 5.0231307782193034e-48
final: 3.266239495519432e-61
final: 2.187514996217005e-81
final: 1.979657878680375e-97
Conflated PDF:  0.049999999999999996

编辑 3:

我实现了以下代码,它似乎可以工作,而且,我设法解决了 quad 的问题,如果我将 quad 更改为 fixed_quad 并规范化 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 user_conflate_pdf_2(pdfs):
"""
Compute conflation of given pdfs.

[ARGS]
- pdfs: PDFs numpy array of shape (n, x)
where n is the number of PDFs
and x is the variable space.

[RETURN]
A 1d-array of normalized conflated PDF.
"""
# conflate
conflation = np.array(pdfs).prod(axis=0)
# normalize
conflation /= conflation.sum()
return conflation

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):
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)]
print('Conflated PDF: ', conflated_pdf)
return conflated_pdf

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()

# User 2:
plt.xlabel("domain")
plt.ylabel("pdf")
plt.title("User Conflated PDF 2")
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]
user_graph=user_conflate_pdf_2(dists)
print('Final User Conflated PDF 2 : ', 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: ', np.array(my_graph))

这是输出:

我的问题是,我知道我需要标准化 PDF 列表。但是,假设我没有规范化 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()

我没有规范化的混合代码图:

【问题讨论】:

  • 在 scipy 文档中对这一行的语法(接受的参数等)进行一些研究:denom = quad(prod_pdf, lb, ub, args=(dists))[0]
  • 您正在将一个数组(具有多个值)传递给一个需要标量、单个数字的函数。检查回溯并确定哪个参数是错误的!
  • @S3DEV 我了解这条线是如何工作的,但在问题 (stackoverflow.com/questions/64346110/…) 中,答案表明可以实现集成。我尝试修改获得多个分布列表(可能不是规范分布)的代码并执行相同的方法,但我不断收到相同的错误。
  • @hpaulj 我了解这条线的工作原理,但在问题 (stackoverflow.com/questions/64346110/…) 中,答案表明可以实现集成。我尝试修改获得多个分布列表(可能不是规范分布)的代码并执行相同的方法,但我不断收到相同的错误。
  • 这个小错误发生在哪里哦?如果没有追溯,我们将无法帮助您。我无法在脑海中运行这样的代码!

标签: python arrays list numpy scipy


【解决方案1】:

ipython 会话中,我复制了您的代码。在我之前的阅读中,它看起来并不完整且可运行。但是通过几个导入它确实会运行并产生您的错误:

In [1]: from scipy.integrate import quad
In [2]: from scipy import stats
In [3]: def prod_pdf(x,pdfs):
   ...:     prod=np.ones(pdfs[0].shape[0])
   ...:     for pdf in pdfs:
   ...:         prod=prod*pdf
   ...:     return prod
   ...: 
   ...: def conflate_pdf(x,dists,lb,ub):
   ...:     denom = quad(prod_pdf, lb, ub, args=(dists))[0]
   ...:     return prod_pdf(x,dists)/denom
   ...: 
   ...: lb=-10
   ...: ub=10
   ...: domain=np.arange(lb,ub,.01)
   ...: 
   ...: dist_1 = stats.norm.pdf(domain, 2,1)
   ...: dist_2 = stats.norm.pdf(domain, 2.5,1.5)
   ...: dist_3 = stats.norm.pdf(domain, 2.2,1.6)
   ...: dist_4 = stats.norm.pdf(domain, 2.4,1.3)
   ...: dist_5 = stats.norm.pdf(domain, 2.7,1.5)
   ...: 
   ...: dists=[dist_1, dist_2, dist_3, dist_4, dist_5]
   ...: graph=conflate_pdf(domain, dists,lb,ub)
   ...: 

回溯

Traceback (most recent call last):
  File "<ipython-input-3-a55a08f59f08>", line 22, in <module>
    graph=conflate_pdf(domain, dists,lb,ub)
  File "<ipython-input-3-a55a08f59f08>", line 8, in conflate_pdf
    denom = quad(prod_pdf, lb, ub, args=(dists))[0]
  File "/usr/local/lib/python3.8/dist-packages/scipy/integrate/quadpack.py", line 351, in quad
    retval = _quad(func, a, b, args, full_output, epsabs, epsrel, limit,
  File "/usr/local/lib/python3.8/dist-packages/scipy/integrate/quadpack.py", line 463, in _quad
    return _quadpack._qagse(func,a,b,args,full_output,epsabs,epsrel,limit)
TypeError: only size-1 arrays can be converted to Python scalars
    

错误出现在编译代码中,因此不提供更多信息。所以我们不得不求助于检查输入和输出。

我首先想到quad 的参数有问题。所以可以肯定的是我扔了一些照片。

In [5]: def prod_pdf(x,pdfs):
   ...:     prod=np.ones(pdfs[0].shape[0])
   ...:     for pdf in pdfs:
   ...:         prod=prod*pdf
   ...:     return prod
   ...: 
   ...: def conflate_pdf(x,dists,lb,ub):
   ...:     print(lb, ub, dists)
   ...:     denom = quad(prod_pdf, lb, ub, args=(dists,))[0]
   ...:     return prod_pdf(x,dists)/denom
   ...: 

 ....
-10 10 [array([2.14638374e-32, 2.41991991e-32, 2.72804284e-32, ...,
       6.41980576e-15, 5.92770938e-15, 5.47278628e-15]), .  

上下界看起来没问题,dists 是一个列表。在一个更简单的情况下,我测试了数组的边界并得到了不同的错误。

那么prod_pdf 会被调用吗?

In [6]: def prod_pdf(x,pdfs):
   ...:     print(x, pdfs)
   ...:     prod=np.ones(pdfs[0].shape[0])
   ...:     for pdf in pdfs:
   ...:         prod=prod*pdf
   ...:     return prod
   ...: 
   ....

0.0 [array([2.14638374e-32, 2.41991991e-32, 2.72804284e-32, ...,
       6.41980576e-15, 5.92770938e-15, 5.47278628e-15]), ....

所以 prod_pdf 被调用,带有 0 和 dists 列表;期望值。

那么返回的prod 是什么?

In [8]: def prod_pdf(x,pdfs):
   ...:     prod=np.ones(pdfs[0].shape[0])
   ...:     for pdf in pdfs:
   ...:         prod=prod*pdf
   ...:     print(prod)
   ...:     return prod
   ...
[1.09076800e-97 1.55234627e-97 2.20861552e-97 ... 3.72095218e-40
 2.98464396e-40 2.39335035e-40]

它的形状是什么?

In [9]: def prod_pdf(x,pdfs):
   ...:     prod=np.ones(pdfs[0].shape[0])
   ...:     for pdf in pdfs:
   ...:         prod=prod*pdf
   ...:     print(prod.shape)
   ...:     return prod
   ...: 
....
(2000,)

哎呀! quad 集成了一个标量函数。 prod_pdf 应该返回一个标量,一个数字,而不是 2000 个值。这就是_quadpack._qagse 抱怨的错误。问题不在于quad 的输入,而在于您的函数返回的值。

现在我知道要查找什么,错误很明显。

如果我们人为地将其截断为 1 个值,quad 会运行而不会出错。

In [10]: def prod_pdf(x,pdfs):
    ...:     prod=np.ones(pdfs[0].shape[0])
    ...:     for pdf in pdfs:
    ...:         prod=prod*pdf
    ...:     print(prod.shape)
    ...:     return prod[0]

我将完成所有这些调试步骤(进行大量编辑),以便您看到我必须经历的步骤。

【讨论】:

  • 感谢您的回答。好吧,我将代码修改为 EDIT 1。但是,我不断收到同样的错误。此外,如果您在以下链接 (stackoverflow.com/questions/64346110/…) 中查看问题的答案,答案能够集成并生成合并 PDF 的图,我只是想达到该步骤,但使用列表而不是获取 pdf在功能上。看看链接,你就会明白我在这条评论中的意思
  • 我没有看过你更大的问题或那个链接。我的重点是标题错误 - size-1 问题。如果函数返回多个值,quad 将不起作用。在我测试的prod_pdf 中,它返回了一个与您的dists, (2000,) 之一大小相同的数组。那是错误的。 quad 的目的是执行一维积分,只返回 一个 浮点数。
  • 我明白你的意思,我通过 Scipy 中的函数进一步了解它及其变量。我提到的链接没有产生这个错误。我想如果您看一下它,它可能会对您有所帮助(了解我在代码中犯的错误,以便它可以类似于用户的答案以及我的代码中可能缺少的内容)和我(进一步了解发生此错误的原因以及我的代码和用户代码有什么不同)你能看看吗?
  • 链接的问题有同样的错误。答案使用不同的prod_pdf,它返回一个数字。只要你返回prod=np.ones(pdfs[0].shape[0]) 或相同大小的东西,你就会得到这个size-1 错误。 denom=quad(...) 行应该产生 one 值,而不是 2000。
  • 好的,所以我认为这里的问题是 prod_pdf 函数是它返回数组而不是导致此问题的单个变量。我查看了他的代码并单独运行它,我设法发现它正在打印出单个变量并设法得到一个变量作为分母。我试图调整我的代码来做到这一点,但相反,它继续获得整个数组的产品。请参阅已编辑的问题 Edit 2
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-28
  • 1970-01-01
相关资源
最近更新 更多