python 速度 memmap_python-如何有效地切片memmap?

目前,我正在处理非常适合我的内存的巨大数据集,因此我使用np.memmap.但是在某些时候,我必须将我的数据集分为训练和测试.

当我想使用一些索引数组切片np.memmap时,我发现了这种情况:

(下面可以找到代码和内存分配)

Line # Mem usage Increment Line Contents

================================================

7 29.340 MB 0.000 MB def my_func2():

8 29.340 MB 0.000 MB ARR_SIZE = (1221508/4,430)

9 29.379 MB 0.039 MB big_mmap = np.memmap('big_mem_test.mmap',shape=ARR_SIZE, dtype=np.float64, mode='r')

10 38.836 MB 9.457 MB idx = range(ARR_SIZE[0])

11 2042.605 MB 2003.770 MB sub = big_mmap[idx,:]

12 3046.766 MB 1004.160 MB sub2 = big_mmap[idx,:]

13 3046.766 MB 0.000 MB return type(sub)

但是,如果我想进行连续切片,我会使用以下代码:

Line # Mem usage Increment Line Contents

================================================

15 29.336 MB 0.000 MB def my_func3():

16 29.336 MB 0.000 MB ARR_SIZE = (1221508/4,430)

17 29.375 MB 0.039 MB big_mmap = np.memmap('big_mem_test.mmap',shape=ARR_SIZE, dtype=np.float64, mode='r')

18 29.457 MB 0.082 MB sub = big_mmap[0:1221508/4,:]

19 29.457 MB 0.000 MB sub2 = big_mmap[0:1221508/4,:]

请注意,在第18,19行的第二个示例中,没有内存分配,整个操作要快得多.

在第11行的第一个示例中,有一个分配,因此在切片期间会读取整个big_mmap矩阵.但是第12行更令人惊讶的是还有另一个分配.进行更多此类操作,您很容易耗尽内存.

当我拆分数据集时,索引是相当随机的并且不是连续的,所以我不能使用big_mmap [start:end ,:]表示法.

我的问题是:

还有其他方法可以让我切片memmap而不将整个数据读取到内存吗?

为什么在对索引进行切片时将整个矩阵读到内存中(示例一)?

为什么要再次读取并分配数据(第一个示例行12)?

解决方法:

您在第一个示例中看到的双重分配并不是由于memmap行为引起的;相反,这是由于numpy的ndarray类如何实现__getitem__所致.当使用列表对ndarray进行索引时(如您的第一个示例),将从源数组中复制数据.使用切片对象为索引建立索引后,将在源数组中创建一个视图(不复制任何数据).例如:

In [2]: x = np.arange(16).reshape((4,4))

In [3]: x

Out[3]:

array([[ 0, 1, 2, 3],

[ 4, 5, 6, 7],

[ 8, 9, 10, 11],

[12, 13, 14, 15]])

In [4]: y = x[[0, 2], :]

In [5]: y[:, :] = 100

In [6]: x

Out[6]:

array([[ 0, 1, 2, 3],

[ 4, 5, 6, 7],

[ 8, 9, 10, 11],

[12, 13, 14, 15]])

y是来自x的数据的副本,因此更改y对x无效.现在通过切片为数组建立索引:

In [7]: z = x[::2, :]

In [8]: z[:, :] = 100

In [9]: x

Out[9]:

array([[100, 100, 100, 100],

[ 4, 5, 6, 7],

[100, 100, 100, 100],

[ 12, 13, 14, 15]])

关于第一个问题,我不知道有什么方法可以让您创建包含整个数组的任意切片,而无需将整个数组读入内存.您可能会考虑两个选项(除了您已经讨论过的HDF5 / PyTables之类的东西之外):

>如果您正在访问培训的内容,依次测试集(而不是将它们作为两个完整的数组进行操作),您可以轻松编写一个小型包装器类,该包装器类的__getitem__方法使用您的索引数组从memmap中提取适当的样本(即,training [i]返回big_mmap [training_ids [一世]])

>将数组拆分为两个单独的文件,其中仅包含训练或测试值.然后,您可以使用两个单独的memmap对象.

标签:python,numpy

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
np.memmap是numpy库中的一个函数,用于创建一个内存映射文件。通过内存映射文件,可以将一个大型数组存储在磁盘上,但是可以像操作内存中的数组一样对其进行访问和操作。\[1\] 使用np.memmap函数可以创建一个内存映射文件,并将数据写入其中。可以指定文件路径、数据类型、打开模式和数组的形状。例如,可以使用np.memmap创建一个内存映射文件,并将数据写入其中:\[1\] ```python import numpy as np data = np.array(\[1, 2, 3, 4, 5\]) fp = np.memmap('your/file/path/xxx.npy', dtype='your_dtype', mode='w+', shape=your_shape) fp\[:\] = data\[:\] ``` 可以通过指定偏移量和元素的形状来读取内存映射文件中的数据。例如,可以使用np.memmap创建一个内存映射文件,并通过偏移量和元素的形状来读取数据:\[1\] ```python import numpy as np ele = np.memmap('your/file/path/xxx.npy', dtype='your_dtype', mode='r', shape=your_ele_shape, offset=index*your_ele_shape*byte_of_dtype) ``` np.memmap函数的默认文件打开方式是'r+',即可读可写。可以通过指定mode参数来修改文件打开方式。\[2\] 总之,np.memmap是numpy库中用于创建内存映射文件的函数,可以方便地对大型数组进行读写操作。它在处理特别大的数组时非常有用,可以将数据存储在磁盘上,同时可以像操作内存中的数组一样对其进行访问和操作。\[3\] #### 引用[.reference_title] - *1* [python numpy.memmap](https://blog.csdn.net/qq_35898332/article/details/126270386)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [np.memmap读取大文件](https://blog.csdn.net/dejing6575/article/details/101474251)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值