如何根据值在dict中找到5个连续的递增/递减键/值对

时间:2016-10-19 04:02:49

标签: python date dictionary collections

我是DBA并尝试根据管理请求获取一些数据。我也是python的新手。 我输入如下(几百条记录),标题为Date和Value。我将这些数据放入字典(日期为关键字)。现在我试图遍历字典,试图找到任何连续5行的升序或降序值(NOT Keys)。 此外,我正在寻找5个连续的值不是> 5.

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

对于上面的输入数据,我期待以下输出:

(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

(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

解决此问题的最佳方法是什么?

1 个答案:

答案 0 :(得分:0)

以下方法适用于Python 2.最好将数据作为按日期排序的列表,因此它首先根据日期将字典转换为有序列表。

然后创建一个比较每个相邻条目的列表,如果它上升,则存储1,等于0和降序-1。然后,它使用groupby()将此列表分组为相似的值。如果每组的长度恰好是4,那么您将有5个条目:

import itertools

def pairwise(iterable):
    "s -> (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]

这会给你以下输出:

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']]           

如果您使用的是Python 3,则需要对cmp()进行编码。

pairwise()是一个众所周知的Python配方,用于从列表中读取连续的条目对。