0

我想找到数据框中两列之间的差异(以天为单位)(更具体地说,在 graphlab SFrame 数据结构中)。

我试图编写几个函数来做到这一点,但我似乎无法创建一个足够快的函数。速度是我现在的问题,因为我有大约 8000 万行要处理。

我尝试了两种不同的功能,但都太慢了:

t2_colname_str 和 t1_colname_str 参数是我要使用的列名,并且两列都包含 datetime.datetime 对象。

循环

def diff_days(sframe_obj,t2_colname_str,t1_colname_str):
    import graphlab as gl
    import datetime as datetime

    # creating the new column name to be used later
    new_colname = str(t2_colname_str[:-9] + "_DiffDays_" + t1_colname_str[:-9])
    diff_days_list = []

    for i in range(len(sframe_obj[t2_colname_str])):
        t2 = sframe_obj[t2_colname_str][i]
        t1 = sframe_obj[t1_colname_str][i]
        try:
            diff = t2 - t1
            diff_days = diff.days
            diff_days_list.append(diff_days)
        except TypeError:
            diff_days_list.append(None)

    sframe_obj[new_colname] = gl.SArray(diff_days_list)

列表理解

我知道这不是列表推导的预期目的,但我只是尝试了一下,看看它是否更快。

def diff_days(sframe_obj,t2_colname_str,t1_colname_str):
    import graphlab as gl
    import datetime as datetime

    # creating the new column name to be used later
    new_colname = str(t2_colname_str[:-9] + "_DiffDays_" + t1_colname_str[:-9])

    diff_days_list = [(sframe_obj[t2_colname_str][i]-sframe_obj[t1_colname_str][i]).days if sframe_obj[t2_colname_str][i] and sframe_obj[t1_colname_str][i] != None else None for i in range(len(sframe_obj[t2_colname_str]))]

    sframe_obj[new_colname] = gl.SArray(diff_days_list)

补充说明

我一直在使用 Dato 的 GraphLab-Create 和他们的 SFrame 数据结构,主要是因为它并行化了所有计算,这使得我的分析速度非常快,并且它有一个很棒的机器学习应用程序库。如果您还没有检查过,这是一个很棒的产品。

GraphLab 用户指南可以在这里找到:https ://dato.com/learn/userguide/index.html

4

1 回答 1

0

我很高兴您找到了一种可行的方法,但是 SArrays 允许向量操作,因此您不需要遍历列的每个元素。SArrays 会迭代,但它们真的很慢。

不幸的是,SArray 不支持对日期时间类型的向量操作,因为它们不支持“timedelta”类型。你可以这样做:

diff = sframe_obj[t2_colname].astype(int) - sframe_obj[t1_colname].astype(int)

这会将列转换为 UNIX 时间戳,然后执行矢量化差异操作,这应该非常快……至少比转换为 NumPy 快。

于 2016-03-25T17:15:47.413 回答