有效地将一个函数应用于两个pandas数据帧

2024-06-09 16:51:28 发布

您现在位置:Python中文网/ 问答频道 /正文

我有两个具有相同索引和列名的DatetimeIndexed数据帧。大约826万行,每行44列,将数据帧连接起来,然后使用10分钟的时间间隔应用groupby,得到大约6884个组。然后迭代匹配的列对,为每个组和列对返回一个值。在

下面的解决方案可以在XeonE5-2697 v3上运行34分钟,所有数据帧都可以放入内存中。在

我认为应该有一种更有效的方法来计算这两个数据帧,也许使用Dask?在

尽管我不清楚如何对Dask数据帧执行基于时间的groupby。在

def circular_mean(burst_veldirection, burst_velspeed):
    x = y = 0.
    for angle, weight in zip(burst_veldirection.values, burst_velspeed.values):
        x += math.cos(math.radians(angle)) * weight
        y += math.sin(math.radians(angle)) * weight

    mean = math.degrees(math.atan2(y, x))
    if mean < 0:
        mean = 360 + mean
    return mean

def circ_mean(df):
    results = []
    for x in range(0,45):
        results.append(circular_mean(df[str(x)], df[str(x) + 'velspeed']))
    return results

burst_veldirection_velspeed = burst_veldirection.join(burst_velspeed, rsuffix='velspeed')

result = burst_veldirection_velspeed.groupby(pd.TimeGrouper(freq='10Min')).apply(circ_mean)

Example short HDF file containing前10000条记录覆盖23分钟


Tags: 数据dfdef时间mathmeanresultsdask
1条回答
网友
1楼 · 发布于 2024-06-09 16:51:28

这并不能让你远离groupby,但是只要从元素角度转换到numpy函数,我的速度就提高了大约8倍。在

def circ_mean2(df):
    df2 = df.iloc[:, 45:].copy()
    df1 = df.iloc[:, :45].copy()
    x = np.sum(np.cos(np.radians(df1.values))*df2.values, axis=0)
    y = np.sum(np.sin(np.radians(df1.values))*df2.values, axis=0)
    arctan = np.degrees(np.arctan2(y, x))
    return np.where(arctan>0, arctan, arctan+360).tolist()

100行比较(随机数据):

^{pr2}$

在10000:

%timeit burst_veldirection_velspeed.groupby(pd.TimeGrouper(freq='10Min')).apply(circ_mean) 
1 loop, best of 3: 6.65 s per loop

%timeit burst_veldirection_velspeed.groupby(pd.TimeGrouper(freq='10Min')).apply(circ_mean2)
1 loop, best of 3: 709 ms per loop

相关问题 更多 >