python - Iterating through a dictionary using dates -


can 1 me how iterate through dictionary dates, have data set this

data=[{u'a': u'd', u'b': 100.0, u'c': 201l, u'd': datetime.datetime(2007, 12, 29, 0, 0), u'e': datetime.datetime(2008, 1, 1, 6, 27, 41)},       {u'a': u'w', u'b': 100.0, u'c': 201l, u'd': datetime.datetime(2007, 12, 29, 0, 0), u'e': datetime.datetime(2008, 2, 4, 6, 27, 41)},       {u'a': u'w', u'b': 100.0, u'c': 202l, u'd': datetime.datetime(2007, 12, 30, 0, 0), u'e': datetime.datetime(2008, 1, 1, 4, 20, 44)},       {u'a': u'd', u'b': 100.0, u'c': 202l, u'd': datetime.datetime(2007, 12, 30, 0, 0), u'e': datetime.datetime(2008, 3, 11, 6, 27, 41)},       {u'a': u'd', u'b': 100.0, u'c': 202l, u'd': datetime.datetime(2007, 12, 30, 0, 0), u'e': datetime.datetime(2008, 5, 8, 11, 2, 41)},       {u'a': u'd', u'b': 100.0, u'c': 203l, u'd': datetime.datetime(2008, 1, 2, 0, 0), u'e': datetime.datetime(2008, 6, 1, 6, 27, 41)},       {u'a': u'w', u'b': 100.0, u'c': 204l, u'd': datetime.datetime(2008, 2, 9, 0, 0), u'e': datetime.datetime(2008, 4, 21, 12, 30, 51)},       {u'a': u'd', u'b': 100.0, u'c': 204l, u'd': datetime.datetime(2008, 2, 9, 0, 0), u'e': datetime.datetime(2008, 8, 15, 15, 45, 10)}] 

how can bring dictionary of below format

res={u'201l':(1,0,1),(2,1,0),(3,0,0),(4,0,0).. on till (12,0,0), u'202l':(1,1,0),(2,0,0),(3,0,1),(4,0,0),(5,0,1)...(12,0,0), u'203l':(1,0,0),(2,0,0),(3,0,0),(4,0,0),(5,1,0)...(12,0,0), u'204l':(1,0,0),(2,0,0),(3,0,0),(4,1,0),(5,0,0),(6,0,0,(7,0,0),(8,0,1)...(12,0,0)} 

where 1, 2, 3 first, second month , on card issue date i.e 201l issue date datetime.datetime(2007, 12, 29, 0, 0), 202l datetime.datetime(2007, 12, 30, 0, 0)

first month means 2007-12-29 2008-1-29

  (1,0,1)---where 1 first month   0 no of times w   1 no of times d 

i tried

data_dict=defaultdict(counter) date_dic={} x in data:   a,b,c,d=x['a'],x['c'],x['d'],x['e']   data_dict[b][a] += 1 key , value in data_dict.items():    date_dic[key] = tuple(map(datetime.date.isoformat, (c,d)))    value in range(1,30):       if value not x: continue 

i have been stuck after if loop can add in above format.i end getting output,

defaultdict(<class 'collections.counter'>, {201l: counter({u'd': 1, u'w': 1}), 202l: counter({u'd': 2, u'w': 1}), 203l: counter({u'd': 1}), 204l: counter({u'd': 1, u'w': 1})}) 

i'd create list of dates, find 'bucket' put each item list.

you can create new dates relative starting point using datetime.timedelta() objects:

startdate = data[0]['d'] buckets = [startdate + datetime.timedelta(days=30) * in xrange(12)] 

now have 12 dates compare else against, know bucket put each subsequent value in:

>>> buckets [datetime.datetime(2007, 12, 29, 0, 0), datetime.datetime(2008, 1, 28, 0, 0), datetime.datetime(2008, 2, 27, 0, 0), datetime.datetime(2008, 3, 28, 0, 0), datetime.datetime(2008, 4, 27, 0, 0), datetime.datetime(2008, 5, 27, 0, 0), datetime.datetime(2008, 6, 26, 0, 0), datetime.datetime(2008, 7, 26, 0, 0), datetime.datetime(2008, 8, 25, 0, 0), datetime.datetime(2008, 9, 24, 0, 0), datetime.datetime(2008, 10, 24, 0, 0), datetime.datetime(2008, 11, 23, 0, 0)] 

we can use bisect module find matching bucket:

from bisect import bisect  bisect(buckets, somedate) - 1  # returns value 0 - 11 

we create such buckets per user need keep track of buckets in separate mapping. we'll create buckets on fly needed fit current transaction date.

next, use collections.defaultdict instance track per-key tallies (key c in input):

from collections import defaultdict  res = defaultdict(list) empty_counts = {'d': 0, 'w': 0} 

this creates list buckets hold, , empty counts dictionary deposits , withdrawals. used dictionary here because much easier work having manipulate (immutable) tuples later on. did not include month number (1 - 12); no point, have index each bucket (0 - 11), , can have variable number of buckets.

we need create buckets , counters needed fit current date in; instead of scanning throuh data find max transaction date per user expand our buckets , counts list needed:

def expand_buckets(buckets, bucket_counts, start, transaction):     # function modifies buckets , bucket_counts lists in-place     if not buckets:         # initialize lists         buckets.append(start)         bucket_counts.append(dict(empty_counts))      # keep adding 30-day spans until can fit transaction date     while buckets[-1] + datetime.timedelta(days=30) < transaction:         buckets.append(buckets[-1] + datetime.timedelta(days=30))         bucket_counts.append(dict(empty_counts)) 

now can start counting:

per_user_buckets = defaultdict(list)  entry in data:     user = entry['c']     type = entry['a']     transaction_date = entry['e']     buckets = per_user_buckets[user]     bucket_counts = res[user]     expand_buckets(buckets, bucket_counts, entry['d'], transaction_date)      # count transaction date entries per bucket     bucket = bisect(buckets, transaction_date) - 1     bucket_counts[bucket][type] += 1 

the bisect call makes picking right bucket easy , fast.

the result example input is:

>>> pprint(dict(res)) {201l: [{'d': 1, 'w': 0},         {'d': 0, 'w': 1}],  202l: [{'d': 0, 'w': 1},         {'d': 0, 'w': 0},         {'d': 1, 'w': 0},         {'d': 0, 'w': 0},         {'d': 1, 'w': 0}],  203l: [{'d': 0, 'w': 0},         {'d': 0, 'w': 0},         {'d': 0, 'w': 0},         {'d': 0, 'w': 0},         {'d': 0, 'w': 0},         {'d': 1, 'w': 0}],  204l: [{'d': 0, 'w': 0},         {'d': 0, 'w': 0},         {'d': 0, 'w': 1},         {'d': 0, 'w': 0},         {'d': 0, 'w': 0},         {'d': 0, 'w': 0},         {'d': 1, 'w': 0}]} 

Comments

Popular posts from this blog

Why does Ruby on Rails generate add a blank line to the end of a file? -

keyboard - Smiles and long press feature in Android -

node.js - Bad Request - node js ajax post -