gpt4 book ai didi

python-3.x - 在空心方形薄片内生成随机均匀分布点的 Pythonic 方法

转载 作者:行者123 更新时间:2023-12-04 02:28:51 24 4
gpt4 key购买 nike

假设我们有一个大小为 n 的空心方形薄片。也就是说,我们有一个 nxn 正方形,从中删除了一个 k*l 矩形(1<=k,l<=n-2)。我想计算这种空心方形薄片内 2 个随机、均匀分布的点之间距离的平均值。
为简单起见,让我们考虑 n=3、k=l=1 或一个 3x3 的正方形,其中心的单位正方形已被移除

我为 numpy 编写了这段代码,但它至少有两个问题:我必须丢弃所有生成的点的大约 1/9,并且删除 numpy.array 元素需要大量 RAM:

    x,y = 3*np.random.random((2,size,2))
x = x[
np.logical_not(np.logical_and(
np.logical_and(x[:,0] > 1, x[:,0] < 2),
np.logical_and(x[:,1] > 1, x[:,1] < 2)
))
]
y = y[
np.logical_not(np.logical_and(
np.logical_and(y[:,0] > 1, y[:,0] < 2),
np.logical_and(y[:,1] > 1, y[:,1] < 2)
))
]
n = min(x.shape[0], y.shape[0])

UPD:这里 size是我要计算平均值的样本量。
有没有一种优雅的方法可以立即生成这些点,而不删除不合适的点?

UPD:这是仅供引用的完整代码:
def calc_avg_dist(size):
x,y = 3*np.random.random((2,size,2))
x = x[
np.logical_not(np.logical_and(
np.logical_and(x[:,0] > 1, x[:,0] < 2),
np.logical_and(x[:,1] > 1, x[:,1] < 2)
))
]
y = y[
np.logical_not(np.logical_and(
np.logical_and(y[:,0] > 1, y[:,0] < 2),
np.logical_and(y[:,1] > 1, y[:,1] < 2)
))
]
n = min(x.shape[0], y.shape[0])
diffs = x[:n,:] - y[:n,:]
return np.sum(np.sqrt(np.einsum('ij,ij->i',diffs,diffs)))/n

最佳答案

去除中心后,有 8 个区域应该包含点。这些是它们的左下角:

In [350]: llcorners = np.array([[0, 0], [1, 0], [2, 0], [0, 1], [2, 1], [0, 2], [1, 2], [2, 2]])

这些区域是 1x1,因此它们具有相同的面积并且同样可能包含给定的随机点。下面选择 size左下角:
In [351]: corner_indices = np.random.choice(len(llcorners), size=size)

现在生成单位正方形中的 size (x,y) 坐标:
In [352]: unit_coords = np.random.random(size=(size, 2))

将这些添加到之前选择的左下角:
In [353]: pts = unit_coords + llcorners[corner_indices]
pts 的形状为 (size, 2) 。这是一个带有 size = 2000 的情节:
In [363]: plot(pts[:,0], pts[:,1], 'o')
Out[363]: [<matplotlib.lines.Line2D at 0x11000f950>]

plot

更新以解决更新的问题...

以下函数将上述想法推广到包含矩形空心的矩形形状。矩形仍然被认为是九个区域,中间区域是空心。随机点在区域内的概率由区域的面积决定; numpy.random.multinomial 用于选择每个区域的点数。

(我确信这段代码有优化的空间。)
from __future__ import division

import numpy as np


def sample_hollow_lamina(size, outer_width, outer_height, a, b, inner_width, inner_height):
"""
(a, b) is the lower-left corner of the "hollow".
"""
llcorners = np.array([[0, 0], [a, 0], [a+inner_width, 0],
[0, b], [a+inner_width, b],
[0, b+inner_height], [a, b+inner_height], [a+inner_width, b+inner_height]])
top_height = outer_height - (b + inner_height)
right_width = outer_width - (a + inner_width)
widths = np.array([a, inner_width, right_width, a, right_width, a, inner_width, right_width])
heights = np.array([b, b, b, inner_height, inner_height, top_height, top_height, top_height])
areas = widths * heights
shapes = np.column_stack((widths, heights))

regions = np.random.multinomial(size, areas/areas.sum())
indices = np.repeat(range(8), regions)
unit_coords = np.random.random(size=(size, 2))
pts = unit_coords * shapes[indices] + llcorners[indices]

return pts

例如,
In [455]: pts = sample_hollow_lamina(2000, 5, 5, 1, 1, 2, 3)

In [456]: plot(pts[:,0], pts[:,1], 'o', alpha=0.75)
Out[456]: [<matplotlib.lines.Line2D at 0x116da0a50>]

In [457]: grid()

plot

请注意,参数不必是整数:
In [465]: pts = sample_hollow_lamina(2000, 3, 3, 0.5, 1.0, 1.5, 0.5)

In [466]: plot(pts[:,0], pts[:,1], 'o', alpha=0.75)
Out[466]: [<matplotlib.lines.Line2D at 0x116e60390>]

In [467]: grid()

plot

关于python-3.x - 在空心方形薄片内生成随机均匀分布点的 Pythonic 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37101001/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com