我正在研究 Monte Carlo 辐射传输代码,它模拟通过介质发射光子并对它们的随机游走进行统计建模。它运行缓慢,一次发射一个光子,所以我想对其进行矢量化并一次运行大约 1000 个光子。
我已经将光子穿过的板划分为光学深度 0
和 depth
之间的 nlayers
切片。实际上,这意味着我有 nlayers + 2
区域(nlayers
加上平板上方的区域和平板下方的区域)。在每一步,我都必须跟踪每个光子穿过哪些层。
假设我已经知道两个光子从第 0 层开始。一个迈出一步并在第 2 层结束,另一个迈出一步并在第 6 层结束。这由数组 表示过去现在
看起来像这样:
[[ 0 2]
[ 0 6]]
我想生成一个 traveled_through
数组 (nlayers + 2)
列和 2 行,描述光子 i
是否穿过层 j
(包含端点)。它看起来像这样(nlayers = 10
):
[[ 1 1 1 0 0 0 0 0 0 0 0 0]
[ 1 1 1 1 1 1 1 0 0 0 0 0]]
我可以通过遍历光子并单独生成每一行 traveled_through
来做到这一点,但这相当慢,并且在某种程度上破坏了一次运行许多光子的意义,所以我宁愿不要那样做。
我尝试按如下方式定义数组:
traveled_through = np.zeros((2, nlayers)).astype(int)
traveled_through[ : , np.min(pastpresent, axis = 1) : np.max(pastpresent, axis = 1) + ] = 1
想法是,在给定的光子行中,从起始层到结束层(包括结束层)的索引将设置为 1,所有其他保持为 0。但是,我收到以下错误:
traveled_through[ : , np.min(pastpresent, axis = 1) : np.max(pastpresent, axis = 1) + 1 ] = 1
IndexError: invalid slice
我最好的猜测是 numpy 不允许使用此方法对数组的不同行进行不同的索引。有没有人对如何为任意数量的光子和任意数量的层生成 traveled_through
提出建议?
最佳答案
如果两个光子总是从 0 开始,您或许可以按如下方式构建数组。
首先设置变量...
>>> pastpresent = np.array([[0, 2], [0, 6]])
>>> nlayers = 10
...然后构建数组:
>>> (pastpresent[:,1][:,np.newaxis] + 1 > np.arange(nlayers+2)).astype(int)
array([[1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]])
或者如果光子具有任意起始层:
>>> pastpresent2 = np.array([[1, 7], [3, 9]])
>>> (pastpresent2[:,0][:,np.newaxis] < np.arange(nlayers+2)) &
(pastpresent2[:,1][:,np.newaxis] + 1 > np.arange(nlayers+2)).astype(int)
array([[0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0]])
关于python - 以不同方式切片 numpy 数组的不同行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27068035/