【问题标题】:Python Quickest Method to Iteratively Slice List of Date StringsPython 对日期字符串列表进行迭代切片的最快方法
【发布时间】:2015-12-11 04:17:30
【问题描述】:

我有一长串日期字符串,例如['2011-01-01','2015-05-05']。在 n 个字符串的列表中,我需要选择第 i 个字符串并找到字符串 i:n 的最新日期。我可以这样做,但过程很慢,需要数小时才能列出数十万个字符串。 我缺少哪些代码优化?示例代码如下。

import numpy as np

d = np.random.choice(xrange(0, 1000), size=100000, replace=True).tolist()
d = [str(item) for item in d]

total = len(d)
for i in xrange(total):
    this_slice = d[i:total]
    greatest = max(this_slice)
    if i % 1000 == 0:  # To track progress
        print i 

这些例子进行得足够快。使用实际的日期字符串,而不是示例中的数字字符串,要慢得多。我已经精确地计时了执行时间,但是对于 600,000 个日期字符串,它似乎需要大约 30-60 分钟。

这是我的数据代码的更精确表示:

import pandas as pd

i = 0
rows = df.shape[0]
for date in df['date']:  # date is 'YYYY-MM-DD'
   this_slice = df['date'][i:rows]
   df['new_date'] = max(this_slice)
   if i % 1000 == 0:  # To track progress
       print i
   i += 0

我已经将日期字符串转换为日期时间对象,使它们成为整数(首先删除了'-'),并且速度并没有更快。必须有更快的方法来编写此代码!

【问题讨论】:

  • 你可以使用数据库吗?
  • 看起来您正在使用 pandas。对吗?
  • 将它们推入 SQLite 并使用您最喜欢的 orm。

标签: python string date


【解决方案1】:

如果您从头到尾进行计算,那么算法的效率将会大大提高,这样您就可以重复使用最大值:

import numpy as np

d = np.random.choice(xrange(0, 1000), size=100000, replace=True).tolist()
d = [str(item) for item in d]

total = len(d)
greatest = d[total-1]
for i in reversed(xrange(total)):
    greatest = max(greatest, d[i])
    if i % 1000 == 0:  # To track progress
        print i

【讨论】:

    【解决方案2】:

    熊猫应该加快速度:

    import pandas as pd
    
    df = pd.DataFrame({'date_string': ['2017-01-01', '2011-12-01', '2015-05-05', '2010-10-01']})
    df['dates'] = pd.to_datetime(df.date_string)
    df['new_date'] = df.dates
    
    for i in range(len(df)):
        df.loc[i, 'new_date'] = df.dates[i:].max()
    

    现在df 看起来像这样:

      date_string      dates   new_date
    0  2017-01-01 2017-01-01 2017-01-01
    1  2011-12-01 2011-12-01 2015-05-05
    2  2015-05-05 2015-05-05 2015-05-05
    3  2010-10-01 2010-10-01 2010-10-01
    

    【讨论】:

    • 我正在使用熊猫,抱歉,我的问题初稿中并不清楚。 pandas 在这个循环中仍然很慢,因为它从顶部开始切片。
    【解决方案3】:

    由于您以严格的顺序迭代外循环中的列表,因此您可以将最大日期的索引保留在剩余切片中,直到您通过,从而避免每次都调用 max。注: argmax 需要整数或浮点数,因此请事先转换日期

     rows = df.shape[0]
     max_remaining_idx = -1
     for i in xrange(rows):  # date is 'YYYY-MM-DD'
         if i > max_remaining_idx:
            max_remaining_idx = df['date'][i:].argmax()
         df['new_date'] = df['date'][max_remaining_idx]
         if i % 1000 == 0:  # To track progress
             print i
    

    【讨论】:

    • 其实@Oliver Pellier-Cuit 的方法更好。
    猜你喜欢
    • 2014-07-08
    • 2017-05-29
    • 2021-05-09
    • 2012-02-12
    • 2020-08-30
    • 1970-01-01
    • 2021-11-20
    • 1970-01-01
    相关资源
    最近更新 更多