How to find 5 consecutive increasing/decreasing key/value pairs in dict based on the value
<p>I am a DBA and trying to get some data as per management request. I am also new to python.
I have input like below(Few hundreds of records) with out the headers Date and Value. I put this data into a dictionary (Date as key). Now I am trying to loop through the dictionary for trying to find any 5 consecutive rows with either ascending or descending values (NOT Keys).
Also I am looking for exactly 5 consecutive values not >5.</p>

<pre><code>Date            value
2015-11-16      112.33
2015-11-17      116.12
2015-11-18      115.52
2015-11-19      117.51
2015-11-20      117.91
2015-11-23      118.07
2015-11-24      119.35
2015-11-25      117.23
2015-11-27      118.43
2015-11-30      117.41
2015-12-01      116.82
2015-12-02      116.13
2015-12-03      114.83
2015-12-04      117.25
</code></pre>

<p>For the above input data I am expecting the following output:</p>

<pre><code>(5 consecutive ascending values)
2015-11-18  115.52
2015-11-19  117.51
2015-11-20  117.91
2015-11-23  118.07
2015-11-24  119.35
</code></pre>

<p>and</p>

<pre><code>(5 consecutive descending values)
2015-11-27      118.43
2015-11-30      117.41
2015-12-01      116.82
2015-12-02      116.13
2015-12-03      114.83
</code></pre>

<p>What is the best way to approach this problem?</p>

<p>The following approach should work for Python 2. It is best to work with the data as a list ordered by date, so it first converts the dictionary into an ordered list based on the dates.</p>

<p>It then creates a list comparing each adjacent entry, if it ascends it stores <code>1</code>, equal <code>0</code> and descending <code>-1</code>. It then uses the <code>groupby()</code> to group this list into similar values. If the length of each group is exactly 4, then you have a run of 5 entries:</p>

<pre><code>import itertools

def pairwise(iterable):
    "s -&gt; (s0,s1), (s1,s2), (s2, s3), ..."
    a, b = itertools.tee(iterable)
    next(b, None)
    return itertools.izip(a, b)

data = {
    "2015-11-16" : "112.33",
    "2015-11-17" : "116.12",
    "2015-11-18" : "115.52",
    "2015-11-19" : "117.51",
    "2015-11-20" : "117.91",
    "2015-11-23" : "118.07",
    "2015-11-24" : "119.35",
    "2015-11-25" : "117.23",
    "2015-11-27" : "118.43",
    "2015-11-30" : "117.41",
    "2015-12-01" : "116.82",
    "2015-12-02" : "116.13",
    "2015-12-03" : "114.83",
    "2015-12-04" : "117.25"}

# Convert dict back to an ordered list
sorted_by_date = [[k, data[k]] for k in sorted(data.keys())]

# Compare adjacent entries
data_cmp = [[cmp(v2[1], v1[1]), v1, v2] for v1, v2 in pairwise(sorted_by_date)]

for k, g in itertools.groupby(data_cmp, key=lambda x: x[0]):
    elements = list(g)
    if len(elements) == 4:
        if k == 1:
            print "Ascending", [v1 for c, v1, v2 in elements] + [v2]
        else:
            print "Descending", [v1 for c, v1, v2 in elements] + [v2]
</code></pre>

<p>This would give you the following output:</p>

<pre class="lang-none prettyprint-override"><code>Ascending [['2015-11-18', '115.52'], ['2015-11-19', '117.51'], ['2015-11-20', '117.91'], ['2015-11-23', '118.07'], ['2015-11-24', '119.35']]
Descending [['2015-11-27', '118.43'], ['2015-11-30', '117.41'], ['2015-12-01', '116.82'], ['2015-12-02', '116.13'], ['2015-12-03', '114.83']]           
</code></pre>

<p>If you are using Python 3, <code>cmp()</code> will need to be coded. </p>

<p><a href="https://docs.python.org/2/library/itertools.html?highlight=pairwise#recipes" rel="nofollow"><code>pairwise()</code></a> is a well know Python recipe for reading consecutive entry pairs out of a list.</p>

python date dictionary collections