代码优化-按月份比较两个datetime列,并且创建新列的速度太慢

问题描述 投票:1回答:2

我正在尝试在Pandas数据框中创建一个新列。如果数据框中的其他两个日期列共享同一月,则此新列应以1作为值,否则为0。此外,我需要检查ID是否与我之前保存在其他地方的ID列表匹配。并仅用1标记它们。我有一些代码,但是它没有用,因为我要处理近十亿行。

my_list_of_ids = df[df.bool_column == 1].id.values

def my_func(date1, date2):
    for id_ in df.id:
        if id_ in my_list_of_ids:
            if date1.month == date2.month:
                my_var = 1
            else:
                my_var = 0
        else:
            my_var = 0
    return my_var

df["new_column"] = df.progress_apply(lambda x: my_func(x['date1'], x['date2']), axis=1)

[等待30分钟,仍然为0%。任何帮助表示赞赏。

更新(添加示例):

id   |    date1   |    date2     | bool_column |  new_column |
id1    2019-02-13    2019-04-11     1                  0
id1    2019-03-15    2019-04-11     0                  0
id1    2019-04-23    2019-04-11     0                  1 
id2    2019-08-22    2019-08-11     1                  1
id2      ....
id3    2019-09-01    2019-09-30     1                  1
.
.
.

我需要做的是将ID为1的ID保存在我的bool_column中,然后循环浏览数据框中的所有ID,并检查它们是否在以前创建的列表中(= 1)。然后,我想比较date1和date2列的月份和年份,如果它们相同,则在它们的马赫数处创建一个值为1的new_column,否则为0。

python-3.x pandas
2个回答
0
投票

熊猫这样做的方法是

mask = ((df['date1'].month == df['date2'].month) & (df['id'].isin(my_list_of_ids)))
df['new_column'] = mask.replace({False: 0, True: 1})

由于您的数据集很大,这将花费一些时间,但应比使用apply更快


0
投票

处理月份匹配的最佳方法是在熊猫中使用矢量化,并执行以下操作:

new_column = (df.date1.dt.month == df.date2.dt.month).astype(int)

即,避免在apply()上使用DataFrame(这可能是迭代的),并利用基础的numpy向量化。此类功能的门户几乎总是位于Series功能和属性系列上,例如日期的dt系列。

幸运的是,您已经预先计算了bool_column中的id_list成员身份,因此要添加成员身份作为条件,只需执行以下操作:

new_column = ((df.date1.dt.month == df.date2.dt.month) & df.bool_column).astype(int)

再次,两个&中的Series利用矢量化。您将停留在布尔空间中直至结尾,然后使用int强制转换为astype(int)

通过我认为示例数据中存在微小错误的方式,第三行的new_column值应为0,因为您的bool_column值为0

© www.soinside.com 2019 - 2024. All rights reserved.