简体   繁体   English

如何在 Python 中创建一个二维数组,其中每列都有不同的随机元素数

[英]How to create a 2D array in Python where each column has a different and random number of elements

I'm writing a Monte Carlo simulation of photons arriving at a detector.我正在编写到达探测器的光子的蒙特卡罗模拟。 The total number of detected photons N_detected follows a Poisson distribution (which I'm generating using scipy.stats.poisson ) and the time of detection of every single photon follows a given probability distribution function (PDF).检测到的光子N_detected遵循泊松分布(我使用scipy.stats.poisson生成)并且每个光子的检测时间遵循给定的概率分布 function (PDF)。 In order to generate the time of detection of the N_detected photons I generate N_detected random numbers between 0 and 1 with the numpy.random.random() function and use the Inverse Transform Method .为了生成N_detected光子的检测时间,我使用numpy.random.random() function 生成介于 0 和 1 之间的N_detected随机数,并使用Inverse Transform Method

I have to run the simulation several times.我必须多次运行模拟。 So, in order to avoid iterating a lot of times, I'd like to do every simulation at once using numpy arrays.因此,为了避免重复很多次,我想使用 numpy arrays 一次进行每个模拟。 As a final result, I'd like to obtain a 2D array of N_sim columns where every column corresponds to a different simulation and contains the generated times of detection.作为最终结果,我想获得一个由N_sim列组成的二维数组,其中每一列对应于不同的模拟,并包含生成的检测时间。 The problem is that each simulation produces a different number of photons (since it's random) and I don't find the way to create the 2D arrray with columns of different lengths.问题是每个模拟都会产生不同数量的光子(因为它是随机的),而且我找不到创建具有不同长度列的 2D 阵列的方法。

One idea I had is creating all the columns with the same length (the largest N_deteceted ) and fill the not needed elements with NaN and the rest with the random numbers I need, but I don't know I could do that.我的一个想法是创建具有相同长度(最大N_deteceted )的所有列,并用NaN和 rest 用我需要的随机数填充不需要的元素,但我不知道我能做到这一点。

This is the best I've been able to do so far:这是迄今为止我能做到的最好的:

import numpy as np
import numpy.ma as ma
from scipy.stats import poisson

beta = 0.0048    # Parameter of the PDF

""" Inverse of the time CDF (needed for the Inverse transform method) """

def inverse_time_cdf(x):
    return -np.log( (np.exp(-1000*beta)-1)*x + 1 )/beta


""" Simulation of N_sim experiments through the inverse transfrom method """

T = 1000    # Duration of the experiment [s]
rate = 3.945    # [events/s]
lam = rate*T    # Poisson distribution parameter

def photon_arrival_simulation(N_sim):
    N_detection = poisson.rvs(lam, size = N_sim)    # Number of detections in each experiment
    t = np.array([inverse_time_cdf(np.random.random(N)) for N in N_detection])

    return N_detection, t

If possible, I wanted to avoid the loop used in the list comprehension of the photon_arrival_simulation() function and also obtain a 2D array instead of an array of arrays (since I can't do array operation such as taking a log on an array of arrays).如果可能的话,我想避免在photon_arrival_simulation() function 的列表理解中使用的循环,并且还获得一个二维数组而不是 arrays 的数组(因为我不能进行数组操作,例如在数组上log数组)。

I don't know if I should be posting this question here or in Physics Stack Exchange , but thanks in advance to anyone.我不知道我是否应该在这里或物理堆栈交换中发布这个问题,但提前感谢任何人。

I don't think it is possible to make a random array with variable lengths along the rows to fill with NaN values without looping somewhere.我认为不可能在不循环某处的情况下沿行创建一个长度可变的随机数组来填充 NaN 值。 But here is how you can resolve the 2d array issue you had, you had the right idea to use NaN.但这是解决二维数组问题的方法,您有使用 NaN 的正确想法。 I would definitely use NaN over masked arrays since masked arrays are more for convenience than for performance.我肯定会在掩码 arrays 上使用 NaN,因为掩码 arrays 更多的是为了方便而不是性能。 Also you should place the docstrings in their appropriate place beneath the function declarations.此外,您应该将文档字符串放在 function 声明下方的适当位置。

def photon_arrival_simulation(N_sim):
    """Simulation of N_sim experiments through the inverse transform method"""

    N_detection = poisson.rvs(lam, size=N_sim)

    rand = np.random.random((len(N_detection), N_detection.max()))

    for i, N in enumerate(N_detection):
        rand[i, N:] = np.nan

    t = inverse_time_cdf(rand)

    return N_detection, t

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM