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

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

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转换为浮点数吗?

  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. # 定义概率矩阵
  4. p = np.array([[10/66, 15/66, 3/66], [20/66, 12/66, 0], [6/66, 0, 0]])
  5. # 初始化X和Y的起始值
  6. x = 0
  7. y = 0
  8. # 创建数组来存储跟踪图
  9. trace_x = []
  10. trace_y = []
  11. # 运行12,000次吉布斯抽样(包括2,000次burn-in)
  12. for i in range(12000):
  13. # 在给定当前Y值的情况下,对X进行抽样
  14. py = np.sum(p[y])
  15. x = np.random.choice([0, 1, 2], p=p[y] / py)
  16. # 在给定当前X值的情况下,对Y进行抽样
  17. px = np.sum(p[:, x])
  18. y = np.random.choice([0, 1, 2], p=p[:, x] / px)
  19. # 在burn-in期之后,将新值附加到跟踪图中
  20. if i >= 2000:
  21. trace_x.append(x)
  22. trace_y.append(y)
  23. # 绘制X和Y的自相关函数
  24. plt.acorr(trace_x, maxlags=50)
  25. plt.title('X的自相关性图')
  26. plt.xlabel('滞后')
  27. plt.ylabel('自相关性')
  28. plt.show()
  29. plt.acorr(trace_y, maxlags=50)
  30. plt.title('Y的自相关性图')
  31. plt.xlabel('滞后')
  32. plt.ylabel('自相关性')
  33. 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?

  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. # Define the probability matrix
  4. p = np.array([[10/66, 15/66, 3/66], [20/66, 12/66, 0], [6/66, 0, 0]])
  5. # Initialize starting values for X and Y
  6. x = 0
  7. y = 0
  8. # Create arrays to store trace plots
  9. trace_x = []
  10. trace_y = []
  11. # Run 12,000 iterations of Gibbs sampling (with 2,000 burn-in)
  12. for i in range(12000):
  13. # Sample a new value for X given the current value of Y
  14. py = np.sum(p[y])
  15. x = np.random.choice([0, 1, 2], p=p[y] / py)
  16. # Sample a new value for Y given the current value of X
  17. px = np.sum(p[:, x])
  18. y = np.random.choice([0, 1, 2], p=p[:, x] / px)
  19. # Append the new values to the trace plots after the burn-in period
  20. if i >= 2000:
  21. trace_x.append(x)
  22. trace_y.append(y)
  23. # Plot the autocorrelation function for X and Y
  24. plt.acorr(trace_x, maxlags=50)
  25. plt.title('Autocorrelation plot for X')
  26. plt.xlabel('Lag')
  27. plt.ylabel('Autocorrelation')
  28. plt.show()
  29. plt.acorr(trace_y, maxlags=50)
  30. plt.title('Autocorrelation plot for Y')
  31. plt.xlabel('Lag')
  32. plt.ylabel('Autocorrelation')
  33. plt.show()

答案1

得分: 3

审查回溯显示错误出现在matplotlib源代码的以下行:

  1. if normed:
  2. 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,如下所示:

  1. plt.acorr(trace_x, maxlags=50, normed=False)

输出:

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

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

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

输出:

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

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

  1. 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

  1. if normed:
  2. 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:

  1. plt.acorr(trace_x, maxlags=50, normed=False)

Output:

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

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

  1. 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:

  1. 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-2.html
匿名

发表评论

匿名网友

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

确定