Подсчитайте количество сообщений в диапазоне дат за интервал. Я использую только Python 2.6.5.
Например Дата начала: 11.12.2014 Дата окончания: 12.12.2014 Время начала: 02:00 Время окончания: 02:05 Интервал: За 1 мин.
Таким образом, это означает, сколько сообщений находится между каждым минутным интервалом с даты начала 11 декабря до даты окончания 12 декабря. Итак, мой вывод будет выглядеть так: (не обязательно иметь строки min и messages)
datetime(2014, 12, 11, 2, 0) min : 0 messages,
datetime(2014, 12, 11, 2, 1) min: 1 message,
datetime(2014, 12, 11, 2, 2) min: 2 messages,
datetime(2014, 12, 11, 2, 3) min: 1 message,
datetime(2014, 12, 11, 2, 4) min : 0 messages,
datetime(2014, 12, 11, 2, 5) min : 0 messages
Я считаю, что я достиг этого, но это очень медленно с большими наборами данных. Я думаю, потому что он использует два цикла, и если второй цикл очень большой, то это занимает очень много времени и делает это для каждой итерации первого цикла. Мне нужна лучшая процедура или alrogithm, чтобы выполнить это?
Изменить: мне нужно включить ноль для интервалов, в которых нет сообщений. Я также пытаюсь найти пик, минимум и среднее значение.
from datetime import date,datetime, timedelta, time
def perdelta(start, end, delta):
curr = start
while curr < end:
yield curr
curr += delta
def rdata(table, fromDate, toDate, fromTime, toTime, interval):
date_to_alert = {}
start_date = datetime(fromDate.year, fromDate.month, fromDate.day, fromTime.hour, fromTime.minute)
end_date = datetime(toDate.year, toDate.month, toDate.day, toTime.hour, toTime.minute)
list_range_of_dates = []
for date_range in perdelta(start_date ,end_date ,interval):
list_range_of_dates.append(date_range)
print list_range_of_dates
index = 0
for date_range in list_range_of_dates:
for row in table:
print('first_alerted_time 1: %s index: %s len: %s' % ( row['first_alerted_time'], index, len(list_range_of_dates)-1))
if row['first_alerted_time'] and row['first_alerted_time'] >= list_range_of_dates[index] and row['first_alerted_time'] < list_range_of_dates[index + 1]:
print('Start date: %s' % list_range_of_dates[index] )
print('first_alerted_time: %s' % row['first_alerted_time'])
print('end date: %s' % list_range_of_dates[index + 1])
if list_range_of_dates[index] in date_to_alert:
date_to_alert[list_range_of_dates[index]].append(row)
else:
date_to_alert[list_range_of_dates[index]] = [row]
elif row['first_alerted_time']:
print('first_alerted_time 2: %s' % row['first_alerted_time'])
index = index + 1
print date_to_alert
for key, value in date_to_alert.items():
date_to_alert[key] = len(value)
print date_to_alert
t1 = []
if date_to_alert:
avg = sum(date_to_alert.values())/len(date_to_alert.keys())
for date_period, num_of_alerts in date_to_alert.items():
#[date_period] = date_to_alert[date_period]
t1.append( [ date_period, num_of_alerts, avg] )
print t1
return t1
def main():
example_table = [
{'first_alerted_time':datetime(2014, 12, 11, 2, 1,45)},
{'first_alerted_time':datetime(2014, 12, 11, 2, 2,33)},
{'first_alerted_time':datetime(2014, 12, 11, 2, 2,45)},
{'first_alerted_time':datetime(2014, 12, 11, 2, 3,45)},
]
example_table.sort()
print example_table
print rdata(example_table, date(2014,12,11), date(2014,12,12), time(00,00,00), time(00,00,00), timedelta(minutes=1))
Обновление: первая попытка улучшения:
Словарь по умолчанию
def default_dict_approach(table, fromDate, toDate, fromTime, toTime, interval):
from collections import defaultdict
t1 = []
start_date = datetime.combine(fromDate, fromTime)
end_date = datetime.combine(toDate, toTime)+ interval
times = (d['first_alerted_time'] for d in table)
counter = defaultdict(int)
for dt in times:
if start_date <= dt < end_date:
counter[to_s(dt - start_date) // to_s(interval)] += 1
date_to_alert = {}
date_to_alert = dict((ts*interval + start_date, count) for ts, count in counter.iteritems())
max_num,min_num,avg = 0,0,0
list_of_dates = list(perdelta(start_date,end_date,interval))
if date_to_alert:
freq_values = date_to_alert.values()
size_freq_values = len(freq_values)
avg = sum(freq_values)/ size_freq_values
max_num = max(freq_values)
if size_freq_values == len(list_of_dates):
min_num = min(freq_values)
else:
min_num = 0
for date_period in list_of_dates:
if date_period in date_to_alert:
t1.append([ date_period.strftime("%Y-%m-%d %H:%M"), date_to_alert[date_period], avg, max_num, min_num])
else:
t1.append([ date_period.strftime("%Y-%m-%d %H:%M"), 0, avg, max_num, min_num])
return (t1,max_num,min_num,avg)
пустой подход
def numpy_approach(table, fromDate, toDate, fromTime, toTime, interval):
date_to_alert = {}
start_date = datetime.combine(fromDate, fromTime)
end_date = datetime.combine(toDate, toTime)+ interval
list_range_of_dates = []
for date_range in perdelta(start_date ,end_date ,interval):
list_range_of_dates.append(date_range)
#print list_range_of_dates
index = 0
times = np.fromiter((d['first_alerted_time'] for d in table),
dtype='datetime64[us]', count=len(table))
print times
bins = np.fromiter(list_range_of_dates,
dtype=times.dtype)
print bin
a, bins = np.histogram(times, bins)
print(dict(zip(bins[a.nonzero()].tolist(), a[a.nonzero()])))