2

基本上我有一个包含数据和价格的元组列表,例如:

[ ("2013-02-12", 200.0), ("2012-02-25", 300.0), ("2000-03-04", 100.0), ("2000-03-05", 50.0)]

该函数需要找到每个月的平均股票价值,然后返回一个包含日期(月和年)和股票价格的元组列表。就像是:

[(250.0, "02-2013"), (100.0, "03-2000"), (50.0, "03-2000")]

这是我到目前为止的代码:

def average_data(list_of_tuples = []):

    list_of_averages = []
    current_year_int = 2013
    current_month_int = 2
    sum_float = float()
    count = 0
    for dd_tuple in list_of_tuples:
        date_str = dd_tuple[0]
        data_float = dd_tuple[1]
        date_list = date_str.split("-")
        year_int = int(date_list[0])
        month_int = int(date_list[1])
        date_year_str = "Date: " + str(month_int) + "-" + str(year_int);


        if month_int != current_month_int:
            average_float = sum_float / count
            average_list = [date_year_str, average_float]
            average_tuple = tuple(average_list)
            list_of_averages.append(average_tuple)
            current_month_int = month_int
            sum_float += data_float


        sum_float += data_float
        count += 1
        current_month_int = month_int
        current_year_int = year_int


    return list_of_averages

它返回一个平均值,但不是正确的,也许不是全部?我曾尝试在互联网上查看示例并询问我的 TA(这是针对 python 类的),但无济于事。有人能指出我正确的方向吗?

编辑:根据建议,if 语句现在应该是这样的,对吗?

    if month_int != current_month_int:
        average_float = sum_float / count
        average_list = [date_year_str, average_float]
        average_tuple = tuple(average_list)
        list_of_averages.append(average_tuple)
        current_month_int = month_int
        sum_float = 0.0
        count = 0
        sum_float += data_float
        count += 1

编辑:感谢大家的帮助!我现在已经运行了代码。

4

4 回答 4

2
>>> lis = [ ("2013-02-12", 200.0), ("2012-02-25", 300.0), ("2000-03-04", 100.0), ("2000-03-05", 50.0)]
>>> from collections import defaultdict
>>> dic = defaultdict(list)
>>> for k,val in lis:
        key = "-".join(k.split('-')[:-1][::-1])             
        dic[key].append(val)
...     
>>> [(sum(v)/float(len(v)),k)  for k,v in dic.items()]

[(200.0, '02-2013'), (300.0, '02-2012'), (75.0, '03-2000')]

上述代码的更简单版本:

lis = [ ("2013-02-12", 200.0), ("2012-02-25", 300.0), ("2000-03-04", 100.0), ("2000-03-05", 50.0)]
dic = {}
for date, val in lis:
    #split the date string at '-' and assign the first  2 items to  year,month
    year, month = date.split('-')[:2]
    #now check if (month,year) is there in the dict
    if (month, year) not in dic:
        #if the tuple was not found then initialise one with an empty list
        dic[month,year] = []

    dic[month,year].append(val) # append val to the (month,year) key

print dic
#Now iterate over key,value items and do some calculations to get the desired output
sol =[]
for key, val in dic.items():
    new_key = "-".join(key)
    avg = sum(val) / len(val)
    sol.append((avg, new_key))
print sol

输出:

#print dic
{('03', '2000'): [100.0, 50.0],
 ('02', '2013'): [200.0],
 ('02', '2012'): [300.0]}
#print sol
[(75.0, '03-2000'), (200.0, '02-2013'), (300.0, '02-2012')]
于 2013-06-10T04:26:17.517 回答
1

我从不确定家庭作业的问题,但我如何通过使用 dict 让你参与其中。我试图使示例保持简单,以便很容易理解发生了什么。

monthly_prices = {}
for dd_tuple in list_of_tuples:
    date, price = dd_tuple
    year, month, _ = date.split("-")
    # this will be a list
    curr_prices = monthly_prices.setdefault((year, month), [])
    curr_prices.append(price)

这使您可以将(year, month)元组映射到价格列表。尝试从那里开始。

setdefault检查映射中是否已存在键,如果不存在,则将键设置为具有默认值。(adefaultdict本质上是一些很好的语法糖,避免了每次迭代都必须初始化一个列表)。

于 2013-06-10T04:17:06.350 回答
1

让我们在您的示例中添加一个重复的日期,这样我们实际上可以看到一些平均值:

l = [ ("2013-02-12", 200.0), ("2012-02-25", 300.0), ("2000-03-04", 100.0), ("2000-03-05", 50.0), ("2013-02-12", 100.0)]

“2013-02-12”出现两次,总计 300.0,所以平均应该是 150.0

我不知道您是否了解过字典或更好的知识,defaultdict,但这就是我正在使用的。使用 defaultdict,您可以在构造函数中指定如果未找到密钥应返回的内容:

from collections import defaultdict

d = default_dict(float) # we'll use this to keep a running sum per date
d_count = default_dict(int) # this one will keep track of how many times the date shows up

我们也可以使用 collections.Counter 来保持计数,但是我们必须在列表上进行一次额外的迭代,这对于一个庞大的列表来说不利于速度。

现在您需要浏览列表,并使用日期作为键将值添加到字典中:

for k,v in l:
    d[k] += v # add the value
    d_count[k] += 1 # increment the count

所以你现在应该有两个字典,看起来像这样:

>>> d
defaultdict(<type 'float'>, {'2013-02-12': 300.0, '2012-02-25': 300.0, '2000-03-05': 50.0, '2000-03-04': 100.0})

>>> d_count
defaultdict(<type 'int'>, {'2013-02-12': 2, '2012-02-25': 1, '2000-03-05': 1, '2000-03-04': 1})

现在,由于两个字典具有相同的键,您可以遍历字典中的项目,并将日期的值除以该日期的计数,得到按日期的平均值。

for k,v in d.iteritems():
    d[k] /= d_count[k]

“d”现在应该包含按日期计算的最终平均值:

>>> d
defaultdict(<type 'float'>, {'2013-02-12': 150.0, '2012-02-25': 300.0, '2000-03-05': 50.0, '2000-03-04': 100.0})

>>> d['2013-02-12']
150.0

>>> for k,v in d.iteritems():
print k, v

2013-02-12 150.0
2012-02-25 300.0
2000-03-05 50.0
2000-03-04 100.0
于 2013-06-10T04:21:19.340 回答
0

在 if 循环中,sum_float 和 count 不会为 0,因此随着程序的进行,平均值会持续数月。所以尝试这样做,它应该可以解决你的问题。还有一点与您的逻辑有关,您是否认为您的元组列表是否排序为一个,如果不是,它可能会导致您的逻辑复杂化。

于 2013-06-10T04:10:40.203 回答