当绘制自相关函数图时,出现UFuncTypeError。

huangapple go评论102阅读模式
英文:

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)

输出:

当绘制自相关函数图时,出现UFuncTypeError。

解决方案 2. 如果需要规范化的值,首先将输入转换为浮点数:

plt.acorr(np.array(trace_x, dtype=float), maxlags=50)

输出:

当绘制自相关函数图时,出现UFuncTypeError。

解决方案 3. 可以在 matplotlib 的代码中应用修复,将就地运算符更改为常规赋值:

correls = correls / np.sqrt(np.dot(x, x) * np.dot(y, y))

输出(与解决方案 2 相同):

当绘制自相关函数图时,出现UFuncTypeError。

我为此向 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:

当绘制自相关函数图时,出现UFuncTypeError。

Solution 2. If normalised values are needed, cast the input to float first:

plt.acorr(np.array(trace_x, dtype=float), maxlags=50)

Output:

当绘制自相关函数图时,出现UFuncTypeError。

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

当绘制自相关函数图时,出现UFuncTypeError。

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.

huangapple
  • 本文由 发表于 2023年5月8日 02:19:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/76195580.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定