Python 大量Dask计算导致内存问题

Python 大量Dask计算导致内存问题,python,pandas,dask,Python,Pandas,Dask,我正在进行一项任务,需要确定两个地理空间点之间的距离在250米以内,并且在20分钟内出现。我的数据集大约有120万行和10列。因此,我需要通过1.2M**2的计算来确定距离、时间差以及它们是否符合我的标准 我已经能够运行下面的代码,在这里我创建了10000个Dask对象,可以毫无问题地进行计算。然而,当我尝试测试100000个对象时,Dask遇到了内存限制,我看到了大量的CPU交换使用。为了清楚起见,我在一个32核的节点上运行它,该节点有125 GB的内存 诚然,我对Dask还很陌生,所以我想知

我正在进行一项任务,需要确定两个地理空间点之间的距离在250米以内,并且在20分钟内出现。我的数据集大约有120万行和10列。因此,我需要通过1.2M**2的计算来确定距离、时间差以及它们是否符合我的标准

我已经能够运行下面的代码,在这里我创建了10000个Dask对象,可以毫无问题地进行计算。然而,当我尝试测试100000个对象时,Dask遇到了内存限制,我看到了大量的CPU交换使用。为了清楚起见,我在一个32核的节点上运行它,该节点有125 GB的内存

诚然,我对Dask还很陌生,所以我想知道:有没有比处理10000行块更好的方法来解决这个问题

#!/usr/bin/env python
import pandas as pd
import numpy as np
import dask.dataframe as dd
from dask.array import sqrt
import time
import multiprocessing as mp


df = pd.read_hdf(...) # Used to select single item for comparison
ddf = dd.read_hdf(...) # Used for Dask operations

def distCheck(item,df=ddf):
    '''
    Determine if any records in df are within 250m of item and within 20
    minutes of item. Return Dask object for calculation.
    '''   

    dist = sqrt(((ddf.LCC_x1-item.LCC_x1)**2+(ddf.LCC_y1-item.LCC_y1)**2))
    distcrit = dist[dist < 250]

    delta = (ddf.Date - item.Date).abs()
    timecrit = delta[delta < np.timedelta64(20,'m')]

    res1 = ddf.copy()
    res1['dist'] = dist
    res1['delta'] = delta
    res1 = res1.loc[(distcrit.index) & (timecrit.index) & (idcrit.index)]
    res1['MatchMMSI'] = item.MMSI
    res1['MatchVoy'] = item.Voyage

    out = res1
    return out


def getDaskCalls(start,stop):
    '''
    Get Dask objects to assess temporal and spatial proximity for df 
    indices from start to stop.
    '''
    # Kick off multiprocessing pool, submit, and close    
    pool = mp.Pool(processes=32)

    daskers = []
    for i in range(start,stop):
        result = pool.apply_async(distCheck,args=(df.iloc[i,:],ddf,))
        daskers.append(result)

    dasky = [i.get() for i in daskers]
    pool.close()    
    return dasky


def runDask(calls):
    result = pd.DataFrame([],columns=calls[0].columns)
    output = dd.compute(calls)
    result = pd.concat([result]+[i for i in output[0] if i.shape[0] != 0])

    return result


###
### Process
###

# Get initial timestamp
start = time.time()

# Create Dask Calls & determine duration
dcalls = getDaskCalls(0,10000)
callsCreated = time.time()

# Print time required to create calls
print("Dask Calls Created.")
print(callsCreated-start)

# Compute the calls with Dask
print("Computing...")
result = runDask(dcalls)

# Print the time for computation
computation = time.time()
print("   ...Done.")
print(computation-callsCreated)

不禁要问,是否值得考虑使用专为此类问题设计的产品?像一个地理空间数据库,用空间索引存储数据点?或者需求阻止了这一点?您不需要逐行应用距离计算,这本质上是一个幼稚的for循环。你应该用数组数学和奇妙的索引来做。请参见此处的幻灯片51+:@paisanco我无权访问服务器上的ESRI许可证,并且我对其他地理空间数据库存储方法不太熟悉。你能推荐一个吗?@PaulH谢谢你的提示!我会采纳你的建议。ESRI之外的一些选项包括Postgresql的PostGIS扩展或MySQL空间扩展。不禁要问,是否值得考虑使用针对此类问题设计的工具?像一个地理空间数据库,用空间索引存储数据点?或者需求阻止了这一点?您不需要逐行应用距离计算,这本质上是一个幼稚的for循环。你应该用数组数学和奇妙的索引来做。请参见此处的幻灯片51+:@paisanco我无权访问服务器上的ESRI许可证,并且我对其他地理空间数据库存储方法不太熟悉。你能推荐一个吗?@PaulH谢谢你的提示!我会使用你的建议。除了ESRI之外,还有一些选项包括Postgresql的PostGIS扩展,或者MySQL空间扩展。