Как найти реализацию метода в numpy repo

Rohit Pandey спросил: 13 июня 2018 в 11:21 в: python

Я только что прочитал о методе Box-Mueller для генерации обычных случайных величин и хочу узнать, использует ли этот метод в numpy python тот же подход. С этой целью я хочу посмотреть исходный код. Я расчесывался через репозиторий GitHub, но пока не имел никакой удачи. Кажется, что в папке "random" нет кода, который мне интересен. В частности, мне нужен код, который вызывается при вызове -

import numpy as np
rand = np.random.normal(size=10)

Может ли кто-нибудь указать мне к этой части кода и, как правило, объясняют, как эффективно выполнять такие виды поиска.

EDIT: строка кода ниже не очень помогает в этом случае, поскольку она просто указывает на init .py, который не слишком много в нем.

print(numpy.random.__file__)

2 ответа

Rohit Pandey ответил: 13 июня 2018 в 12:29
Фактический код для Box-Mueller находится в файле C - github.com/numpy/numpy/blob/... Я хочу знать, как это связано с методом в файле pyx. Легко ли это проследить?
Есть решение
Zev ответил: 13 июня 2018 в 12:58

Похоже, что код, который вы ищете, находится здесь:

https://github.com/numpy/numpy/blob/464f79eb1d05bf938d16b49da1c39a4e02506fa3/numpy/random/mtrand/mtrand.pyx#L1551

Как вы можете видеть, он находится под random/mtrand/mtrand.pyx. Если вам интересно о .pyx: Cython заявляет:

"Файл .pyx скомпилирован Cython в файл .c, содержащий код модуля расширения Python. Файл .c компилируется компилятором C. в файл .so (или .pyd в Windows), который может быть импортирован непосредственно в сеанс Python.

Вы искали определение normal, поэтому я искал "def normal".

Вот код по этой ссылке:

def normal(self, loc=0.0, scale=1.0, size=None):
    """
    normal(loc=0.0, scale=1.0, size=None)
    Draw random samples from a normal (Gaussian) distribution.
    The probability density function of the normal distribution, first
    derived by De Moivre and 200 years later by both Gauss and Laplace
    independently [2]_, is often called the bell curve because of
    its characteristic shape (see the example below).
    The normal distributions occurs often in nature.  For example, it
    describes the commonly occurring distribution of samples influenced
    by a large number of tiny, random disturbances, each with its own
    unique distribution [2]_.
    Parameters
    ----------
    loc : float or array_like of floats
        Mean ("centre") of the distribution.
    scale : float or array_like of floats
        Standard deviation (spread or "width") of the distribution.
    size : int or tuple of ints, optional
        Output shape.  If the given shape is, e.g., ``(m, n, k)``, then
        ``m * n * k`` samples are drawn.  If size is ``None`` (default),
        a single value is returned if ``loc`` and ``scale`` are both scalars.
        Otherwise, ``np.broadcast(loc, scale).size`` samples are drawn.
    Returns
    -------
    out : ndarray or scalar
        Drawn samples from the parameterized normal distribution.
    See Also
    --------
    scipy.stats.norm : probability density function, distribution or
        cumulative density function, etc.
    Notes
    -----
    The probability density for the Gaussian distribution is
    .. math:: p(x) = \\frac{1}{\\sqrt{ 2 \\pi \\sigma^2 }}
                     e^{ - \\frac{ (x - \\mu)^2 } {2 \\sigma^2} },
    where :math:`\\mu` is the mean and :math:`\\sigma` the standard
    deviation. The square of the standard deviation, :math:`\\sigma^2`,
    is called the variance.
    The function has its peak at the mean, and its "spread" increases with
    the standard deviation (the function reaches 0.607 times its maximum at
    :math:`x + \\sigma` and :math:`x - \\sigma` [2]_).  This implies that
    `numpy.random.normal` is more likely to return samples lying close to
    the mean, rather than those far away.
    References
    ----------
    .. [1] Wikipedia, "Normal distribution",
           https://en.wikipedia.org/wiki/Normal_distribution
    .. [2] P. R. Peebles Jr., "Central Limit Theorem" in "Probability,
           Random Variables and Random Signal Principles", 4th ed., 2001,
           pp. 51, 51, 125.
    Examples
    --------
    Draw samples from the distribution:
    >>> mu, sigma = 0, 0.1 # mean and standard deviation
    >>> s = np.random.normal(mu, sigma, 1000)
    Verify the mean and the variance:
    >>> abs(mu - np.mean(s)) < 0.01
    True
    >>> abs(sigma - np.std(s, ddof=1)) < 0.01
    True
    Display the histogram of the samples, along with
    the probability density function:
    >>> import matplotlib.pyplot as plt
    >>> count, bins, ignored = plt.hist(s, 30, density=True)
    >>> plt.plot(bins, 1/(sigma * np.sqrt(2 * np.pi)) *
    ...                np.exp( - (bins - mu)**2 / (2 * sigma**2) ),
    ...          linewidth=2, color='r')
    >>> plt.show()
    """
    cdef ndarray oloc, oscale
    cdef double floc, fscale    oloc = <ndarray>PyArray_FROM_OTF(loc, NPY_DOUBLE, NPY_ARRAY_ALIGNED)
    oscale = <ndarray>PyArray_FROM_OTF(scale, NPY_DOUBLE, NPY_ARRAY_ALIGNED)    if oloc.shape == oscale.shape == ():
        floc = PyFloat_AsDouble(loc)
        fscale = PyFloat_AsDouble(scale)
        if np.signbit(fscale):
            raise ValueError("scale < 0")
        return cont2_array_sc(self.internal_state, rk_normal, size, floc,
                              fscale, self.lock)    if np.any(np.signbit(oscale)):
        raise ValueError("scale < 0")
    return cont2_array(self.internal_state, rk_normal, size, oloc, oscale,
                       self.lock)

Как упоминалось здесь, в повторяющемся вопросе (который я нашел после ответа), вы также можете попробовать следующее (но в этом случае он, возможно, не получил вас намного дальше, чем вы делали самостоятельно ):

import numpy.random
print(numpy.random.__file__)# /home/adam/.pyenv/versions/datasci/lib/python3.6/site-packages/numpy/random/__init__.py

Чтобы проследить подключение к rk_gauss, вы увидите rk_normal в приведенном выше коде, который ссылается на:

double rk_normal(rk_state *state, double loc, double scale)
{
    return loc + scale*rk_gauss(state);
}

Итак, его:

Здесь и здесь. Я думаю, что это просто вопрос о том, какие другие функции вы интересуете в вызовах.

Zev ответил: 13 июня 2018 в 12:54
Да, rk_normal в normal, а затем вы получите github.com/numpy/numpy/blob/...

Дополнительное видео по вопросу: Как найти реализацию метода в numpy repo

Вычисления в Jupyter Notebook: массивы numpy - основы

NumPy Tutorials : 006 : mgrid, ogrid, and sparse gridded data arrays

NumPy (Python) Dersleri - 1