迭代切割日期字符串列表的Python最快方法

时间:2015-12-11 04:17:31

标签: python string date

我有很长的日期字符串列表,例如['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

我已将日期字符串转换为datetime对象,使它们成为整数(首先删除' - '),并且速度不会更快。必须有一种更快的方式来编写这段代码!

3 个答案:

答案 0 :(得分:3)

如果您从头到尾进行计算,那么算法效率会更高,因此您可以重复使用最大值:

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

答案 1 :(得分:1)

熊猫应加快速度:

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

答案 2 :(得分:0)

由于您以严格的顺序迭代外部循环中的列表,因此您可以将最大日期的索引保留在剩余的切片中,直到您通过,从而使您不必每次都调用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