我有很长的日期字符串列表,例如['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对象,使它们成为整数(首先删除' - '),并且速度不会更快。必须有一种更快的方式来编写这段代码!
答案 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