英文:
when plotting autocorrelation function plot getting UFuncTypeError
问题
当绘制自相关函数图时,出现了"gettingUFuncTypeError: Cannot cast ufunc 'divide' output from dtype('float64') to dtype('int32')"的错误,这个错误发生在注释"# Plot the autocorrelation function for X and Y. do I need to convert trace x and y to float?"之后。我需要将trace x和y转换为浮点数吗?
import numpy as np
import matplotlib.pyplot as plt
# 定义概率矩阵
p = np.array([[10/66, 15/66, 3/66], [20/66, 12/66, 0], [6/66, 0, 0]])
# 初始化X和Y的起始值
x = 0
y = 0
# 创建数组来存储跟踪图
trace_x = []
trace_y = []
# 运行12,000次吉布斯抽样(包括2,000次burn-in)
for i in range(12000):
# 在给定当前Y值的情况下,对X进行抽样
py = np.sum(p[y])
x = np.random.choice([0, 1, 2], p=p[y] / py)
# 在给定当前X值的情况下,对Y进行抽样
px = np.sum(p[:, x])
y = np.random.choice([0, 1, 2], p=p[:, x] / px)
# 在burn-in期之后,将新值附加到跟踪图中
if i >= 2000:
trace_x.append(x)
trace_y.append(y)
# 绘制X和Y的自相关函数
plt.acorr(trace_x, maxlags=50)
plt.title('X的自相关性图')
plt.xlabel('滞后')
plt.ylabel('自相关性')
plt.show()
plt.acorr(trace_y, maxlags=50)
plt.title('Y的自相关性图')
plt.xlabel('滞后')
plt.ylabel('自相关性')
plt.show()
英文:
when plotting autocorrelation function plot gettingUFuncTypeError: Cannot cast ufunc 'divide' output from dtype('float64') to dtype('int32') the error happens after the comment # Plot the autocorrelation function for X and Y. do I need to convert trace x and y to float?
import numpy as np
import matplotlib.pyplot as plt
# Define the probability matrix
p = np.array([[10/66, 15/66, 3/66], [20/66, 12/66, 0], [6/66, 0, 0]])
# Initialize starting values for X and Y
x = 0
y = 0
# Create arrays to store trace plots
trace_x = []
trace_y = []
# Run 12,000 iterations of Gibbs sampling (with 2,000 burn-in)
for i in range(12000):
# Sample a new value for X given the current value of Y
py = np.sum(p[y])
x = np.random.choice([0, 1, 2], p=p[y] / py)
# Sample a new value for Y given the current value of X
px = np.sum(p[:, x])
y = np.random.choice([0, 1, 2], p=p[:, x] / px)
# Append the new values to the trace plots after the burn-in period
if i >= 2000:
trace_x.append(x)
trace_y.append(y)
# Plot the autocorrelation function for X and Y
plt.acorr(trace_x, maxlags=50)
plt.title('Autocorrelation plot for X')
plt.xlabel('Lag')
plt.ylabel('Autocorrelation')
plt.show()
plt.acorr(trace_y, maxlags=50)
plt.title('Autocorrelation plot for Y')
plt.xlabel('Lag')
plt.ylabel('Autocorrelation')
plt.show()
答案1
得分: 3
审查回溯显示错误出现在matplotlib
源代码的以下行:
if normed:
correls /= np.sqrt(np.dot(x, x) * np.dot(y, y))
位于 https://github.com/matplotlib/matplotlib/blob/main/lib/matplotlib/axes/_axes.py。
该错误是由于在使用就地操作时,numpy
库内部防止自动向上转型引起的。这在 SO 用户 poke 的答案中得到了很好的解释 这里。
现在,为了回答问题,我们需要避免就地操作。
因此,对于提问者的特定问题,有三种解决方案:
解决方案 1. 如果不需要规范化的值,可以在 plt.acorr
函数中传递 normed=False
,如下所示:
plt.acorr(trace_x, maxlags=50, normed=False)
输出:
解决方案 2. 如果需要规范化的值,首先将输入转换为浮点数:
plt.acorr(np.array(trace_x, dtype=float), maxlags=50)
输出:
解决方案 3. 可以在 matplotlib 的代码中应用修复,将就地运算符更改为常规赋值:
correls = correls / np.sqrt(np.dot(x, x) * np.dot(y, y))
输出(与解决方案 2 相同):
我为此向 matplotlib 提交了一个拉取请求 这里 并参考了提问者的问题。如果我的拉取请求被批准,我将更新答案。
编辑:
拉取请求已被批准。即使使用包含所有整数的列表或 numpy 数组,acorr
函数也能如预期般工作。
英文:
A look into the traceback reveals that the error is due to the lines
if normed:
correls /= np.sqrt(np.dot(x, x) * np.dot(y, y))
inside the matplotlib
source code at https://github.com/matplotlib/matplotlib/blob/main/lib/matplotlib/axes/_axes.py.
The error appears due to the prevention of automatic upcasting within the numpy
library when using in-place operations. This has been beautifully explained in an answer by SO user: poke here. Now, to answer the OP's question, we need to steer clear of the in-place operation.
So, for the OP's specific problem, there are three solutions:
Solution 1. If normalised values are not needed, the normed=False
can be passed in the plt.acorr
function as an argument as shown below:
plt.acorr(trace_x, maxlags=50, normed=False)
Output:
Solution 2. If normalised values are needed, cast the input to float first:
plt.acorr(np.array(trace_x, dtype=float), maxlags=50)
Output:
Solution 3. The fix can be applied inside the matplotlib's code itself. To change the in-place operator to regular assignment as:
correls = correls / np.sqrt(np.dot(x, x) * np.dot(y, y))
Output (Same as solution 2):
I put a pull request for this to matplotlib here and referred to the OP's question. I will update the answer if my pull-request is approved.
EDIT:
The pull request has been approved. The acorr
function works as expected even when using a list or numpy array with all integers.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论