Reputation: 391
How can I sort these tuples by time interval, say every hour?
[('172.18.74.146', datetime.time(11, 28, 58)), ('10.227.211.244',
datetime.time(11, 54, 19)), ('10.227.215.68', datetime.time(11, 54, 34)),
('10.227.209.139', datetime.time(12, 14, 47)), ('10.227.147.98',
datetime.time(14, 47, 25))]
The result should be:
[["172.18.74.146, 10.227.211.244, 10.227.215.68", "11-12"], etc...]
I tried to use group by, but doesnt get what I want:
for dd in data[1:]:
ips = dd[1].split(",")
dates = dd[2].split(",")
i = 0
while(i < len(dates)):
ips[i] = ips[i].strip()
hour, mins, second = dates[i].strip().split(":")
dates[i] = datetime.time(int(hour), int(mins), int(second))
i+=1
order = [(k, ', '.join(str(s[0]) for s in v)) for k, v in groupby(sorted(zip(ips, dates), key=operator.itemgetter(1)), lambda x: x[1].hour)]
Upvotes: 2
Views: 1048
Reputation: 12022
This should work for you:
from __future__ import print_function
import datetime
import itertools
def iter_len(iterable):
return sum(1 for __ in iterable)
def by_hour(item): # Hour key
timestamp = item[1]
return '{}-{}'.format(timestamp.hour, (timestamp.hour+1) % 24)
def by_half_hour(item): # Half-hour key
timestamp = item[1]
half_hour = timestamp.hour + (0.5 * (timestamp.minute // 30))
return '{:.1f}-{:.1f}'.format(half_hour, (half_hour+0.5) % 24)
def get_results(data, key): # Name this more appropriately
data = sorted(data, key=key)
for key, grouper in itertools.groupby(data, key):
yield (key, iter_len(grouper))
data = [
('172.18.74.146', datetime.time(11, 28, 58)),
('10.227.211.244', datetime.time(11, 54, 19)),
('10.227.215.68', datetime.time(11, 54, 34)),
('10.227.209.139', datetime.time(12, 14, 47)),
('10.227.147.98', datetime.time(14, 47, 25)),
]
print('By Hour')
print(list(get_results(data, by_hour)))
print()
print("By Half Hour")
print(list(get_results(data, by_half_hour)))
Output:
$ ./SO_32081251.py
By Hour
[('11-12', 3), ('12-13', 1), ('14-15', 1)]
By Half Hour
[('11.0-11.5', 1), ('11.5-12.0', 2), ('12.0-12.5', 1), ('14.5-15.0', 1)]
Upvotes: 1
Reputation: 14847
In [17]: a = [('172.18.74.146', datetime.time(11, 28, 58)), ('10.227.211.244',
datetime.time(11, 54, 19)), ('10.227.215.68', datetime.time(11, 54, 34)),
('10.227.209.139', datetime.time(12, 14, 47)), ('10.227.147.98',
datetime.time(14, 47, 25))]
In [18]: [(k, ', '.join(str(s[0]) for s in v)) for k, v in groupby(a, lambda x: x[1].hour)]
Out[18]:
[(11, '172.18.74.146, 10.227.211.244, 10.227.215.68'),
(12, '10.227.209.139'),
(14, '10.227.147.98')]
Upvotes: 3
Reputation: 15157
This is almost what you want. Use the hour to group by:
for k,g in itertools.groupby(order, lambda x: x[1].hour):
print k,list(g)
Results in:
11 [('172.18.74.146', datetime.time(11, 28, 58)), ('10.227.211.244', datetime.time(11, 54, 19)), ('10.227.215.68', datetime.time(11, 54, 34))]
12 [('10.227.209.139', datetime.time(12, 14, 47))]
14 [('10.227.147.98', datetime.time(14, 47, 25))]
Upvotes: 1