gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-04 08:41:00 25 4
gpt4 key购买 nike

我有一些时间数据,从 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/

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