【问题标题】:Memory error when merging two big dataframes合并两个大数据帧时出现内存错误
【发布时间】:2021-01-21 21:47:11
【问题描述】:

我需要一些帮助。

主要问题是用经纬度计算两点之间的距离。我们将巴西划分为 33k 个六边形,列在下面的数据框中:

我一直在尝试将此数据框与其副本合并,因此我将拥有一个包含这些六边形的所有组合的 10 亿行数据框,并使用此函数计算它们之间的距离:

def get_distance(lat_1, lng_1, lat_2, lng_2): 
    d_lat = lat_2 - lat_1
    d_lng = lng_2 - lng_1 

    temp = (  
         np.sin(d_lat / 2) ** 2 
       + np.cos(lat_1) 
       * np.cos(lat_2) 
       * np.sin(d_lng / 2) ** 2
    )
    
    #print('a')

    return 6373.0 * (2 * np.arctan2(np.sqrt(temp), np.sqrt(1 - temp))) * 1.4 * 1000

我尝试将它们与 Pandas 合并,但出现内存错误(需要 8GB),因此我使用 Vaex 库将数据转换为 hdf5 文件。但是,当我尝试将它们与此代码合并时,我得到了同样的错误。

with h5py.File('mergedfs', 'w') as hdf:
    hdf.create_dataset('datasetmerge', data = dvv.join(dvv2, left_on='key', right_on='key2', how='left', allow_duplication=True))

以前有没有人经历过这样的事情?我提前感谢您的帮助。

另外,如果您有任何替代解决方案,我很高兴听到!

【问题讨论】:

  • 您需要一个并行化或核外框架。我不会在这里推荐软件包,但我的工程师在工作中使用过这些 > 250GB 的帧。
  • 内存有限时的另一种选择是读取和操作数据切片,然后将这些切片写入 HDF5 文件。循环执行此操作,直到处理完所有切片。我对 Pandas 不熟悉,所以不知道它是否可以读取切片。你当然可以使用 h5py 或 Pytables 来做到这一点。我刚刚写了一个示例,该示例对 2 个矩阵的元素进行求和并写入另一个文件。看到这个答案:stackoverflow.com/a/65812444/10462884
  • @kcw78 谢谢你的回答!问题是我一直在尝试计算点之间的向量积,但是您的代码计算了两个相等大小的数据集的元素之和,返回了具有相同形状的第三个数据集。我正在寻找一种方法来解决问题,并可能获得分离的输出数据集,以便我可以附加它们并获得 10 亿行帧(33k x 33k)。如何连接两个数据集中的 lat 和 long 列并计算它们之间的向量积以获得所有六边形组合,然后得到一个 4 列的 dset 及其坐标?
  • 是的,我的例子是一个简单的总和。我分享它是为了展示如何读取一段数据并对其进行数学运算。我需要有关文件架构的更多详细信息(h5py/numpy 术语中的 dtype)。目前尚不清楚为什么需要 2 个文件(如果文件 2 是文件 1 的副本)。如果我理解,lat_1lng_1 来自一行,lat_2lng_2 来自另一行。您可以使用 2 个循环来执行此操作,其中外循环 i=1 to 33k 和内循环 j=i to 33k
  • 你真的需要所有的距离吗?

标签: python distance latitude-longitude hdf5 vaex


【解决方案1】:

如果没有您的数据集的 dytpe,我无法编写精确的解决方案。但是,当我查看您的代码和文件图像时,我可以猜测伪代码应该是什么样子。见下文。我为您的 HDF5 文件和数据集使用了假定名称。我使用图像中显示的列/字段名称作为纬度和经度数据。这只是循环,调用get_distance() 来计算距离并将值返回为dist_i_j。注意:我按原样调用您的函数get_distance()。希望这会让你开始。或者,如果您可以提供有关 dtype 的更多信息(或一些示例数据),我可以微调代码。祝你好运!

with h5py.File('not_mergedfs', 'w') as hdf:
    data=h5f['ds_name']
    
    for i in range (32882):
        lat_1 = data[i]['lat']
        lng_1 = data[i]['lon']
  
        for j in range (i+1,32882):
            lat_2 = data[j]['lat']
            lng_2 = data[j]['lon']
    
            dist_i_j = get_distance(lat_1, lng_1, lat_2, lng_2)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-03
    • 2016-08-16
    • 2021-10-19
    相关资源
    最近更新 更多