就地调整numpy.memmap大小

2 投票
2 回答
548 浏览
提问于 2025-04-18 07:00

关于调整 numpy.memmap 大小的代码看起来是可以工作的,但程序所做的更改并没有被保存。

def test_resize_inplace():

    fA = np.memmap('A_r.npy', dtype='uint8', mode='w+', shape=(3,12))

    print "fA"
    print fA

    fA[2][0] = 42

    # resize by creating new memmap
    new_fA = np.memmap('A_r.npy', mode='r+', dtype='uint8', shape=(20,12))

    print 'fA'
    print fA

    print 'new_fA'
    print new_fA

而且当我尝试把调整大小的过程拿掉时,Python 解释器在某一行崩溃了。

print new_fA

下面是相关的代码:

def resize_memmap(fm,sz,tp):
    fm.flush()
    print fm.filename
    new_fm = np.memmap(fm.filename, mode='r+', dtype= tp, shape=sz)
    return new_fm

def test_resize_inplace():

    fA = np.memmap('A_r.npy', dtype='uint8', mode='w+', shape=(3,12))

    print "fA"
    print fA

    fA[2][0] = 42

    sz= (20,12)
    tp= 'uint8'

    new_fA= resize_memmap(fA,sz,type)
    new_fA[9][9]= 111

    print 'fA'
    print fA

    print 'new_fA'
    print new_fA

更新:我试过使用 .flush()

def test_memmap_flush():
    fA = np.memmap('A_r.npy', dtype='uint8', mode='w+', shape=(3,12))

    print "fA"
    print fA

    fA[2][0] = 42

    fA.flush()

# fB = np.memmap('A_r.npy', dtype='uint8', mode='w+', shape=(3,12)) #fails
fB = np.memmap('A_r.npy', dtype='uint8', mode='r+', shape=(3,12))

    print "fB"
    print fB

    print "done"

但是我不明白为什么我不能使用 w+ 模式?

IOError: [Errno 22] 无效的模式 ('w+b') 或文件名: 'A_r.npy'


更新:

好的,我明白了。 w+ 是用来创建文件的,而 r+ 是用来读写文件的。

2 个回答

0

回答:为什么会出现 IO Error: [Errno 22] 错误?

首先,我得承认,这个问题让我困扰了大约六个月,我一度不得不手动解决。

最后,我找到了根本原因。

这个错误只在Windows系统上出现 (在Unix系统上没有出现这个异常)
当一个.memmap()的文件恰好在另一个文件句柄下仍然被打开时,就会出现这个问题。

del aMMAP # first ( does .flush() before closing the underlying fileHandle
#         # next, mmap again, with adjustments you need
aMMAP = np.memmap( ... )

希望这能帮到你
感谢Michael Droettboom

0

这个文件在访问之间可能没有被刷新。你可以试着在一个“with”块中加载一个文件对象,然后再传给memmap:

with open('A_r.npy', 'w') as f:
    fA = np.memmap(f, ...
with open('A_r.npy', 'r') as f:
    fA = np.memmap(f, ...

撰写回答