我已经确认genfromtxt函数(以及从它派生的函数)以静默方式缓存它们在本地目录中处理的远程文件,并在后续调用中使用本地副本,而不检查它是否已更改.
通过查看源文件npyio.py,似乎发生这种情况是因为处理请求的DataSource对象是在不传递相关参数的情况下创建的.当然很容易修改库源来禁用缓存,但是每次升级后我都要重复它.
还有其他解决方案吗?(除了每次删除缓存目录)
研究库源代码后,我意识到可以通过修改numpy数据源模块中名为open的小辅助函数的默认值来实现所需的行为。如上所述,无需修改库源即可实现此目的。这是我附带的代码:
import numpy
from numpy.lib._datasource import DataSource
#def open(path, mode='r', destpath=os.curdir):
def openm(path, mode='r', destpath=None):
ds = DataSource(destpath)
return ds.open(path, mode)
numpy.lib._datasource.open=openm
Run Code Online (Sandbox Code Playgroud)
在调用genfromtxt或从它派生的函数之前必须包含它。但我的研究进一步表明这些函数相当慢,并且在 Windows 中禁用缓存会产生警告 - 这不是由于上面的重新定义,它似乎与 Windows 中mktemp函数的实现
方式有关。此外,缓存的文件和关联的临时目录不会被删除。
这似乎与处理请求的数据源在读取和关闭文件之前超出范围(因此被删除)有关。当执行数据源的析构函数时,它尝试删除数据源的目录,由于文件句柄仍然打开,所以操作失败,因此出现警告。我正在考虑在 genfromtxt 函数中移动数据源实例化。 我确认在 genfromtxt 函数中移动数据源实例化在 Windows 和 Linux 下可以正常工作,因此我认为这是正确的解决方案。
我得出的结论是,最干净的方法是修改numpy库并将缓存参数添加到genfromtxt
以下是对 npyio.py 的必要修改,只需修改几行。genfromtxt 函数原型更改为
def genfromtxt(fname, dtype=float, comments='#', delimiter=None,
skiprows=0, skip_header=0, skip_footer=0, converters=None,
missing='', missing_values=None, filling_values=None,
usecols=None, names=None,
excludelist=None, deletechars=None, replace_space='_',
autostrip=False, case_sensitive=True, defaultfmt="f%i",
unpack=None, usemask=False, loose=True, invalid_raise=True):
Run Code Online (Sandbox Code Playgroud)
to(添加新的缓存参数)
def genfromtxt(fname, dtype=float, comments='#', delimiter=None,
skiprows=0, skip_header=0, skip_footer=0, converters=None,
missing='', missing_values=None, filling_values=None,
usecols=None, names=None,
excludelist=None, deletechars=None, replace_space='_',
autostrip=False, case_sensitive=True, defaultfmt="f%i",
unpack=None, usemask=False, loose=True, invalid_raise=True,cache=True):
Run Code Online (Sandbox Code Playgroud)
打开文件/url 的行从
if isinstance(fname, basestring):
fhd = iter(np.lib._datasource.open(fname, 'rbU')
own_fhd = True
Run Code Online (Sandbox Code Playgroud)
到
if isinstance(fname, basestring):
ds=DataSource('.' if cache==True else None)
fhd = iter(ds.open(fname, 'rbU'if cache==True else 'rbUD'))
own_fhd = True
Run Code Online (Sandbox Code Playgroud)
“D”是 Windows 特定的打开标志(在 Linux 中无害),它标记文件临时,在文件句柄关闭时自动删除。
包装函数版本
def mgenfromtxt(fname,cache=True,**karg):
if cache==False and isinstance(fname, basestring) and numpy.DataSource()._isurl(fname):
ds=numpy.DataSource(None)
fhd = iter(ds.open(fname,'rbUD'))
l1=numpy.genfromtxt(fhd,**karg)
fhd.close()
del ds
return l1
else:
return(numpy.genfromtxt(fname,**karg))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
260 次 |
| 最近记录: |