Python: 我一直收到广播错误,但我不确定如何解决
Python: I keep getting a broadcasting error, but I'm not sure how to fix it
为了我的目的,我正在尝试从这个 link 中调整接受的答案代码:
我正在从事一个项目,该项目要求我以 .csv 文件的形式拍摄热图像,然后从 .csv 文件中获取数据以制作箭头(通过 quiverplot streamplot 等)显示来自图像上最热点(最高像素值)的热流方向。我认为这可以使用图像的渐变来实现,但我不确定如何实现它。
这是我的代码:
import matplotlib.pyplot as plt
import numpy as np
import math
directory = os.chdir(r'user_directory') #Set folder to look in
file = 'data.csv'
data = np.genfromtxt(file, delimiter = ',')
horizontal_min, horizontal_max, horizontal_stepsize = 0, 100, 0.3
vertical_min, vertical_max, vertical_stepsize = 0, 100, 0.5
horizontal_dist = horizontal_max-horizontal_min
vertical_dist = vertical_max-vertical_min
horizontal_stepsize = horizontal_dist / float(math.ceil(horizontal_dist/float(horizontal_stepsize)))
vertical_stepsize = vertical_dist / float(math.ceil(vertical_dist/float(vertical_stepsize)))
xv, yv = np.meshgrid(np.arange(horizontal_min, horizontal_max, horizontal_stepsize),
np.arange(vertical_min, vertical_max, vertical_stepsize))
xv+=horizontal_stepsize/2.0
yv+=vertical_stepsize/2.0
result_matrix = np.asmatrix(data)
yd, xd = np.gradient(result_matrix)
def func_to_vectorize(x, y, dx, dy, scaling=0.01):
plt.arrow(x, y, dx*scaling, dy*scaling), fc="k", ec="k", head_width=0.06,
head_length=0.1)
vectorized_arrow_drawing = np.vectorize(func_to_vectorize)
plt.imshow(np.flip(result_matrix,0), extent=[horizontal_min, horizontal_max, vertical_min,
vertical_max])
vectorized_arrow_drawing(xv, yv, xd, yd, 0.1)
plt.colorbar()
plt.show()
这是我遇到的错误:
ValueError:操作数无法与形状一起广播 (200,335) (200,335) (100,100) (100,100) () </p>
<p>编辑:回溯错误</p>
<pre>ValueError Traceback (most recent call last)
<ipython-input-95-25a8b7e2dff8> in <module>
46
47 plt.imshow(np.flip(result_matrix,0), extent=[horizontal_min,
horizontal_max, vertical_min, vertical_max])
---> 48 vectorized_arrow_drawing(xv, yv, xd, yd, 0.1)
49 plt.colorbar()
50 plt.show()
~\Anaconda3\lib\site-packages\numpy\lib\function_base.py in __call__(self,
*args, **kwargs)
1970 vargs.extend([kwargs[_n] for _n in names])
1971
-> 1972 return self._vectorize_call(func=func, args=vargs)
1973
1974 def _get_ufunc_and_otypes(self, func, args):
~\Anaconda3\lib\site-packages\numpy\lib\function_base.py in
_vectorize_call(self, func, args)
2046 for a in args]
2047
-> 2048 outputs = ufunc(*inputs)
2049
2050 if ufunc.nout == 1:
ValueError: operands could not be broadcast together with shapes (100,168)
(100,168) (100,100) (100,100) ()
我猜错误是由于这对语句引起的:
vectorized_arrow_drawing = np.vectorize(func_to_vectorize)
...
vectorized_arrow_drawing(xv, yv, xd, yd, 0.1)
即使我的猜测是正确的,你应该 post 更多的错误信息。
np.vectorize
使用 broadcasting
组合来自输入的值,并针对每个组合将一组标量值发送到 func_to_vectorize
。
根据错误,5个参数的形状为:
(200,335) (200,335) (100,100) (100,100) ()
()
数组是标量值 0.1。那应该没问题。但它不能将 (200,335) 数组与 (100,100) 数组一起使用。 xv
和 yv
数组与 xd
和 yd
数组不兼容。
你真的需要 xd, yd, xv, yv
都具有相同的形状(或者所有可广播到相同的形状,但在功能上这是一样的)才能使 vectorize
工作。最简单的方法是:
xv, yv = np.meshgrid(np.linspace(horizontal_min, horizontal_max, data.shape[0]),
np.linspace(vertical_min, vertical_max, data.shape[1]))
如果您确实希望在一个方向上比另一个方向有更高的分辨率,另一种方法是使用 scipy.interpolate.interp2d
将 xd
和 yd
插值到 xv
和yv
。但这要复杂得多。
为了我的目的,我正在尝试从这个 link 中调整接受的答案代码:
我正在从事一个项目,该项目要求我以 .csv 文件的形式拍摄热图像,然后从 .csv 文件中获取数据以制作箭头(通过 quiverplot streamplot 等)显示来自图像上最热点(最高像素值)的热流方向。我认为这可以使用图像的渐变来实现,但我不确定如何实现它。
这是我的代码:
import matplotlib.pyplot as plt
import numpy as np
import math
directory = os.chdir(r'user_directory') #Set folder to look in
file = 'data.csv'
data = np.genfromtxt(file, delimiter = ',')
horizontal_min, horizontal_max, horizontal_stepsize = 0, 100, 0.3
vertical_min, vertical_max, vertical_stepsize = 0, 100, 0.5
horizontal_dist = horizontal_max-horizontal_min
vertical_dist = vertical_max-vertical_min
horizontal_stepsize = horizontal_dist / float(math.ceil(horizontal_dist/float(horizontal_stepsize)))
vertical_stepsize = vertical_dist / float(math.ceil(vertical_dist/float(vertical_stepsize)))
xv, yv = np.meshgrid(np.arange(horizontal_min, horizontal_max, horizontal_stepsize),
np.arange(vertical_min, vertical_max, vertical_stepsize))
xv+=horizontal_stepsize/2.0
yv+=vertical_stepsize/2.0
result_matrix = np.asmatrix(data)
yd, xd = np.gradient(result_matrix)
def func_to_vectorize(x, y, dx, dy, scaling=0.01):
plt.arrow(x, y, dx*scaling, dy*scaling), fc="k", ec="k", head_width=0.06,
head_length=0.1)
vectorized_arrow_drawing = np.vectorize(func_to_vectorize)
plt.imshow(np.flip(result_matrix,0), extent=[horizontal_min, horizontal_max, vertical_min,
vertical_max])
vectorized_arrow_drawing(xv, yv, xd, yd, 0.1)
plt.colorbar()
plt.show()
这是我遇到的错误:
ValueError:操作数无法与形状一起广播 (200,335) (200,335) (100,100) (100,100) () </p>
<p>编辑:回溯错误</p>
<pre>ValueError Traceback (most recent call last)
<ipython-input-95-25a8b7e2dff8> in <module>
46
47 plt.imshow(np.flip(result_matrix,0), extent=[horizontal_min,
horizontal_max, vertical_min, vertical_max])
---> 48 vectorized_arrow_drawing(xv, yv, xd, yd, 0.1)
49 plt.colorbar()
50 plt.show()
~\Anaconda3\lib\site-packages\numpy\lib\function_base.py in __call__(self,
*args, **kwargs)
1970 vargs.extend([kwargs[_n] for _n in names])
1971
-> 1972 return self._vectorize_call(func=func, args=vargs)
1973
1974 def _get_ufunc_and_otypes(self, func, args):
~\Anaconda3\lib\site-packages\numpy\lib\function_base.py in
_vectorize_call(self, func, args)
2046 for a in args]
2047
-> 2048 outputs = ufunc(*inputs)
2049
2050 if ufunc.nout == 1:
ValueError: operands could not be broadcast together with shapes (100,168)
(100,168) (100,100) (100,100) ()
我猜错误是由于这对语句引起的:
vectorized_arrow_drawing = np.vectorize(func_to_vectorize)
...
vectorized_arrow_drawing(xv, yv, xd, yd, 0.1)
即使我的猜测是正确的,你应该 post 更多的错误信息。
np.vectorize
使用 broadcasting
组合来自输入的值,并针对每个组合将一组标量值发送到 func_to_vectorize
。
根据错误,5个参数的形状为:
(200,335) (200,335) (100,100) (100,100) ()
()
数组是标量值 0.1。那应该没问题。但它不能将 (200,335) 数组与 (100,100) 数组一起使用。 xv
和 yv
数组与 xd
和 yd
数组不兼容。
你真的需要 xd, yd, xv, yv
都具有相同的形状(或者所有可广播到相同的形状,但在功能上这是一样的)才能使 vectorize
工作。最简单的方法是:
xv, yv = np.meshgrid(np.linspace(horizontal_min, horizontal_max, data.shape[0]),
np.linspace(vertical_min, vertical_max, data.shape[1]))
如果您确实希望在一个方向上比另一个方向有更高的分辨率,另一种方法是使用 scipy.interpolate.interp2d
将 xd
和 yd
插值到 xv
和yv
。但这要复杂得多。