python - 任何存在内存使用的对象,如生成器,但可以在必要时返回一个 numpy 数组?

标签 python arrays numpy generator

我有一些时间数据,从 T0 开始,以 dt 为步长到达 T1。此数据以 dt 的小增量递增,目前存储为 numpy 数组,因此占用大量空间。一种更有效的存储方式是存储 T0、T1 和 dt,例如使用发电机。然而,生成器不适用于许多功能,例如numpy 函数、算术和绘图。我想要一些像生成器一样工作的东西,即只存储 3 个必要的值,然后在必要时生成一个 numpy 数组以用于某些函数等。

是否有任何已经存在的对象可以像这样工作? IE。将必要的数据(3 个值)存储在生成器中,然后在函数或算术中使用时将其自身返回/表示为一个 numpy 数组?内存只会在函数范围内使用,并在超出范围时释放。

编辑解决方案:我创建了一个我想要的实现。事实证明复制生成器很棘手,请参阅 here ,所以我改为存储开始、停止和步骤,并根据需要创建和返回生成器或 numpy 数组。

代码如下:

import numpy as _np

class frange():
    """
    Return an object can be used to generate a generator or an array 
    of floats from start (inclusive) to stop (exclusive) by step. 
    This object stores the start, stop, step and length of
    the data. Uses less memory than storing a large array.

    Example
    -------
    An example of how to use this class to generate some data is
    as follows for some time data between 0 and 2 in steps of
    1e-3 (0.001)::

        $ time = frange(0, 2, 1e-3)

        $ printlen(time) # prints length of frange, just like an array or list

        $ generator = time.get_generator() # gets a generator instance
        $ for i in generator: # iterates through printing each element
        $     print(i)

        $ array = time.get_array() # gets an array instance
        $ newarray = 5 * array # multiplies array by 5


    """
    def __init__(self, start, stop, step):
        """
        Intialises frange class instance. Sets start, top, step and 
        len properties.

        Parameters
        ----------
        start : float
            starting point
        stop : float
            stopping point 
        step : float
            stepping interval
        """
        self._slice = slice(start, stop, step)
        self.len = self.get_array().size
        return None

    def get_generator(self):
        """
        Returns a generator for the frange object instance.

        Returns
        -------
        gen : generator
            A generator that yields successive samples from start (inclusive)
            to stop (exclusive) in step steps.
        """
        s = self._slice
        gen = drange(s.start, s.stop, s.step) # intialises the generator
        return gen

    def get_array(self):
        """
        Returns an numpy array containing the values from start (inclusive)
        to stop (exclusive) in step steps.

        Returns
        -------
        array : ndarray
            Array of values from start (inclusive)
            to stop (exclusive) in step steps.
        """
        s = self._slice        
        array = _np.arange(s.start, s.stop, s.step)
        return array

    def __len__(self):
        return self.len      

def drange(start, stop, step):
    """
    A generator that yields successive samples from start (inclusive)
    to stop (exclusive) in step intervals.

    Parameters
    ----------
    start : float
        starting point
    stop : float
        stopping point 
    step : float
        stepping interval

    Yields
    ------
    x : float
        next sample
    """
    x = start
    if step > 0:
        while x + step <= stop: # produces same behaviour as numpy.arange
            yield x
            x += step
    elif step < 0:
        while x + step >= stop: # produces same behaviour as numpy.arange
            yield x
            x += step
    else:
        raise ZeroDivisionError("Step must be non-zero")

最佳答案

Python 已经有一个存储start, stop, step 属性的类,一个slice

In [523]: s = slice(0, 1, .1)

np.lib.index_tricks 有一个可以扩展切片的类。在这种情况下,它使用 arange:

In [524]: np.r_[s]
Out[524]: array([ 0. ,  0.1,  0.2,  0.3,  0.4,  0.5,  0.6,  0.7,  0.8,  0.9])
In [525]: np.arange(s.start, s.stop, s.step)
Out[525]: array([ 0. ,  0.1,  0.2,  0.3,  0.4,  0.5,  0.6,  0.7,  0.8,  0.9])
In [526]: np.arange(0, 1, .1)
Out[526]: array([ 0. ,  0.1,  0.2,  0.3,  0.4,  0.5,  0.6,  0.7,  0.8,  0.9])

slice 只是存储它的属性;任何计算都是由使用它的代码完成的。如果 step 值是虚数,np.r_ 使用这个技巧来调用 np.linspace

In [527]: np.r_[slice(0,1,11j)]
Out[527]: array([ 0. ,  0.1,  0.2,  0.3,  0.4,  0.5,  0.6,  0.7,  0.8,  0.9,  1. ])

我看不出另一个答案中讨论的生成器与动态运行 arangelinspace 相比有何改进。

如果您正在开发自己的索引类,那么值得您研究一下 index_tricks.py 文件。

关于python - 任何存在内存使用的对象,如生成器,但可以在必要时返回一个 numpy 数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44854593/

相关文章:

python - scipy.optimize.minimize 返回零维数组?

python - Twisted reactor 已停止,但程序并未结束?

python - numpy arctan2 错误或使用问题?

python - 添加堆叠数组 Numpy 的元素

python - 在 NaN 处的 Cumsum 重置

python - 二维 numpy 数组 : remove masked elements

Python读取设备管理器信息

python - 根据特定列值绘制 pandas 数据框的多行的快速方法

php - 从对象数组的单列创建逗号分隔的字符串

java - 更新 2D Java 数组中的对象