【问题标题】:How can I open large (2GB) files and precompute it quicker?如何打开大 (2GB) 文件并更快地进行预计算?
【发布时间】:2021-07-04 23:26:03
【问题描述】:

这是我目前用来打开这个非常大的 matlab 文件的代码:

self.data = {}
f = h5py.File(filepath, 'r')
for k, v in f.items():
    self.data[k] = np.array(v)
self.data = list(self.data.items())
self.data = np.array(self.data)
self.fs = self.data[1][1][0][0]
self.data = self.data[0][1]

print('fs = ', self.fs)
print('DONE. Data read using h5py reader')

完全加载大约需要 3-5 分钟。如何改进此代码以便加快进程?

【问题讨论】:

  • 由于您的代码可以正常运行,因此您可以尝试在codereview.stackexchange.com发布问题
  • 简短的回答是你不能。磁盘 I/O 就是这样
  • @jsotola,我认为这不是一个适合 CR 的问题。太专业了。
  • 您所做的远不止“打开”文件。您将所有根级数据集读取为 np.arrays 并添加到字典 self.data。然后将字典转换为列表,并从列表中创建一个新数组。这意味着您正在读取和操作 2GB 的数据。正如@Mad Physicist 所说:磁盘 I/O 就是这样(而且速度不快)。您需要一次阅读所有内容吗? h5py 旨在访问和使用“类似于”NumPy 数组的 HDF5 数据集。在您的代码中,v 是一个 h5py 对象,其行为类似于一个数组(不加载到内存中)。只保存对象,它会加载得更快。
  • 我将如何只保存对象?

标签: python matlab processing h5py buffering


【解决方案1】:

保存和使用对象很容易。在不知道代码目的的情况下,很难提供有关对象与数组的详细信息。得到变量self.data 后你想做什么?您检索所有数据集,然后继续重新定义self.data。最后,将self.data 分配给第一个数据集的数组。此外,self.fs 指向第二个数据集中的单个值。所以,不清楚为什么要检索所有这些。

如果你只想要第一个数据集中的数据,这样的事情就可以完成。

f = h5py.File(filepath, 'r')
# returns first key from group member names:
dsname = next(iter(f))    #  (name of 1st dataset)
self.data = f[dsname][:]  #  (data from 1st dataset)

如果您想要所有数据集中的名称和数据,这将返回名称和对象的字典。

f = h5py.File(filepath, 'r')
for k, v in f.items():
    self.data[k] = v 

然后,当您需要一个数据数组时,请使用以下方法之一:

arr = data['a dataset name'][:]  # for 1 dataset (when you know the name)
for dsname, obj in data.items():  # loop thru all pairs in data
    arr = obj[:]  # or
    arr = f[dsname][:]

要了解发生了什么,让我们从一些 HDF5 基础知识开始。使用 HDF5 时,了解架构至关重要。数据结构类似于计算机上的文件夹和文件。文件夹是“组”,文件是“数据集”。使用 h5py,您使用字典语法访问组成员,并且您使用 NumPy 数组语法访问数据集。 (h5py 文件对象的行为类似于一个组。)

因此,当您执行 for k,v in f.items() 时,h5py 会为每个组成员返回 key,value 对(代码中的 k,v)。 key对象的名称valueh5py 对象(数据集或其他组)。

拥有数据集后,可以通过 3 种方式访问​​相关数据:

  1. 您可以简单地保存对象并引用它“好像”它是一个 NumPy 数组。
  2. 您可以保存对象的名称,然后在需要对象的数据时,使用数据集名称和关联的组进行检索。
  3. 您可以将数据集值读入 NumPy 数组。 (这就是您的代码所做的。)

注意:我更喜欢方法 #1 和 #2,因为它们在您读取数据之前不会将数据加载到内存中

这是你的代码,我的 cmets 关于每个步骤:

# returns a file object "f" (behaves like a group):
f = h5py.File(filepath, 'r')
# returns key/value pairs of group member names/objects:
for k, v in f.items():
    # adds a dictionary key (object name) with value of an array read from object "v":
    self.data[k] = np.array(v)
# converts the (name,array) dictionary into a list:
self.data = list(self.data.items())
# converts the list into a nd.array of dtype=object:
#    -has 1 row for each dataset with 2 columns: 
#    -column 0: object name, column 1: array of data 
self.data = np.array(self.data)
# reads [0][0] value from array at self.data[1][1] ([0][0] value for 2nd dataset)
self.fs = self.data[1][1][0][0]
# resets data to value from array at self.data[0][1] (array for 1st dataset)
self.data = self.data[0][1]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-28
    • 1970-01-01
    • 2014-11-13
    • 1970-01-01
    • 2020-02-25
    • 2014-03-12
    相关资源
    最近更新 更多