我是Python的新手,来自MATLAB,很久以前来自C。我在MATLAB中编写了一个脚本,它模拟了马尔可夫过程中河流中的沉积物输送。代码随机地将随机直径的圆放置在指定尺寸的矩形区域内。圆是不均匀的尺寸,从指定的尺寸范围中随机抽取。我不知道有多少次我会逐步完成圆圈放置操作,所以我使用while循环来完成这个过程。为了更加面向社区,我正在将MATLAB脚本翻译成Python。我使用在线工具OMPC开始,并从自动翻译版本手动完成(没有那么有用,这并不奇怪)。为了调试代码,我使用了 MATLAB生成的结果通常与Python中的结果进行比较和对比。我似乎很清楚,我已经以一种在脚本中进行计算时引入问题的方式声明了变量。以下是不同代码执行实例之间的一致问题的两个示例。首先,代码生成我认为是数组中的数组,因为脚本返回的结果如下:
此结果是在overlap_logix操作中为以下代码段生成的:
CenterCoord_Array = np.asarray(CenterCoordinates)
Diameter_Array = np.asarray(Diameter)
dist_check = ((CenterCoord_Array[:,0] - x_Center) ** 2 + (CenterCoord_Array[:,1] - y_Center) ** 2) ** 0.5
radius_check = (Diameter_Array / 2) + radius
radius_check_update = np.reshape(radius_check,(len(radius_check),1))
radius_overlap = (radius_check_update >= dist_check)
# Now actually check the overalp condition.
if np.sum([radius_overlap]) == 0:
# The new circle does not overlap so proceed.
newCircle_Found = 1
debug_value = 2
elif np.sum([radius_overlap]) == 1:
# The new circle overlaps with one other circle
overlap = np.arange(0,len(radius_overlap), dtype=int)
overlap_update = np.reshape(overlap,(len(overlap),1))
overlap_logix = (radius_overlap == 1)
idx_true = overlap_update[overlap_logix]
radius = dist_check(idx_true,1) - (Diameter(idx_true,1) / 2)
为变量生成了相同运行的类似结果:
以下是工作MATLAB版本(根据要求)的相同代码片段:
distcheck = ((Circles.CenterCoordinates(1,:)-x_Center).^2 + (Circles.CenterCoordinates(2,:)-y_Center).^2).^0.5;
radius_check = (Circles.Diameter ./ 2) + radius;
radius_overlap = (radius_check >= distcheck);
% Now actually check the overalp condition.
if sum(radius_overlap) == 0
% The new circle does not overlap so proceed.
newCircle_Found = 1;
debug_value = 2;
elseif sum(radius_overlap) == 1
% The new circle overlaps with one other circle
temp = 1:size(radius_overlap,2);
idx_true = temp(radius_overlap == 1);
radius = distcheck(1,idx_true) - (Circles.Diameter(1,idx_true)/2);
在Python版本中,我从列表中创建了数组,以便更轻松地对内容进行操作(代码片段的前两行)。数组结果中的数组和创建数组来访问数据告诉我,我错误地声明了变量类型,但我不确定。此外,一些变量具有大小,例如,(2L,)(数值维度将随着圆放置而改变),其中没有第二维。当我尝试在另一个具有大小(2L,1L)的数组的操作中使用该数组时,这会产生明显的问题。由于这些问题,我开始重塑数组,然后我停止了因为我认为这些是黑客,因为我已经错误地声明了一个或多个变量。其次,对于同一次运行,我遇到了以下错误:
操作:
radius = dist_check(idx_true,1) - (Diameter(idx_true,1) / 2)
发生在上面代码段的底部。我已将整个脚本发布在以下链接中,因为为自己执行脚本可能更有用:
https://github.com/smchartrand/MarkovProcess_Bedload
我已经设置了使用一些初始参数值运行的代码,因此不需要做出决定;这些参数值在基于MATLAB的脚本中产生预期结果,在绘制时看起来像这样:
所以,我似乎特别关注第151-165行的操作问题,具体取决于测试值 np.sum([radius_overlap]),我认为这是因为我错误地声明了变量类型,但我真的不确定。我可以肯定地说,Python版本和MATLAB版本在输出中通过while循环的第一步是一致的,而代码行127则是进入while循环的第二步。在代码中的这一点下面,上面记录的问题最终导致脚本崩溃。有时脚本执行完成15%,有时它不会达到5% - 这是由于圆圈放置的随机性。我正在Spyder(Python 2.7)IDE中准备代码,并将作为我研究的一部分公开分享工作代码。我非常感谢能够提供任何帮助来识别我的错误和python编码实践的误用。
答案 0 :(得分:0)
我相信我已经回答了我自己的问题,也许它会对未来的某些人有用。我可以在以下三个网页找到主要的教学资料:
第三个网页对我来自MATLAB很有帮助。这是修改后的工作python代码片段,它与上面提供的原始片段有关:
dist_check = ((CenterCoordinates[0,:] - x_Center) ** 2 + (CenterCoordinates[1,:] - y_Center) ** 2) ** 0.5
radius_check = (Diameter / 2) + radius
radius_overlap = (radius_check >= dist_check)
# Now actually check the overalp condition.
if np.sum([radius_overlap]) == 0:
# The new circle does not overlap so proceed.
newCircle_Found = 1
debug_value = 2
elif np.sum([radius_overlap]) == 1:
# The new circle overlaps with one other circle
overlap = np.arange(0,len(radius_overlap[0]), dtype=int).reshape(1, len(radius_overlap[0]))
overlap_logix = (radius_overlap == 1)
idx_true = overlap[overlap_logix]
radius = dist_check[idx_true] - (Diameter[0,idx_true] / 2)
最后我很清楚,对于这个例子来说,使用numpy数组与列表来存储填充矩形区域的每次迭代的结果更为直接。对于更正的代码段,这意味着我初始化了变量:
作为numpy数组,而我在发布的问题中将它们初始化为列表。这使得一些数学运算更加简单。我也错误地使用括号()索引变量而不是使用方括号[]的正确方法。以下是我所做的更正示例,它帮助代码按照设想执行:
此示例还显示我遇到了数组维度的问题,我通过变量更正了变量。我仍然不确定我的工作代码是否是以随机方式填充矩形区域的最pythonic或最有效的方式,但我已经成功测试了大约100次。修订后的工作代码可以在这里下载:
Working Python Script to Randomly Fill Rectangular Area with Circles
以下是成功运行工作代码的最终结果的图像:
对我来说,主要的教训是(1)numpy数组对于重复数值计算更有效,(2)我创建的数组的维数并不总是我所期望的那样,并且在建立数组时必须小心。感谢那些查看我的问题并要求澄清的人。