根据Python中的月份列表制作列表

时间:2015-08-18 17:23:04

标签: python list for-loop count append

我正在使用Python制作列表。应该很容易!我不知道为什么我这么挣扎。

我有一些数据,我按日期计算。有一个这样的日期列:

Created on
5/1/2015
5/1/2015
6/1/2015
6/1/2015
7/1/2015
8/1/2015
8/1/2015
8/1/2015

在这种情况下,5月份将有2个单位,6月份将有2个单位,7月份将有1个单位,8月份将有3个单位。

我希望在4月开始的列表中反映出来([4月计数,5月计数,6月计数等...]):

NumberofUnits = [0, 2, 3, 1, 3, 0, 0, 0, 0, 0, 0, 0]  

我有一个很好的月份列表

monthnumbers

Out[69]: [8, 5, 6, 7]

我还有一个unitcounts = [2, 3, 1, 3]的列表,我使用value_counts。

所以这是制作一个零列表并用unitcount列表替换零件的问题,对吗?

出于某种原因,我的所有尝试都要么没有列表,要么列出一个零。

NumberofUnits = [0]*12

for i in range(0,len(monthnumbers)):
    if  **monthnumbers[i] == (i+4):** **This part is wrong**       
        NumberofUnits.append(unitcounts[i])
        s = slice(0,i+1)

我也试过

NumberofUnits = []
for i in range(0, 12):
    if len(NumberofUnits) > i:
        unitcounts[i:]+unitcounts[:i]
        NumberofUnits.append(unitcounts[i])
        s = slice(0,i+1)
    else:
        unitcounts.append(0)

但这并没有考虑到这一事实,在这一轮我的数据从五月开始,所以我需要在第一个插槽中为零。

4 个答案:

答案 0 :(得分:1)

您可以使用collections.counter

计算条目
from collections import Counter

lines = ['5/1/2015', '5/1/2015', ..., '8/1/2015']
month_numbers = [int(line.split("/")[0]) for line in lines]

cnt = Counter(month_numbers)

如果您已经有计数,可以用上面的

替换
from collections import defaultdict

cnt = defaultdict(int, zip(monthnumbers, unitcounts))

并简单地映射到带有(month_number - offset)mod 12的条目:

[x[1] for x in sorted([((i - offset) % 12, cnt[i]) for i in range(1, 13)])]

答案 1 :(得分:1)

如果数据来自文件或任何可迭代的数据,您可以使用OrderedDict,从4/april开始按顺序创建密钥,然后增加您遇到的每个月的计数最终打印最后将按所需顺序排列的值列表:

from collections import OrderedDict

od = OrderedDict((i % 12 or 12, 0) for i in range(4, 16))
# -> OrderedDict([(4, 0), (5, 0), (6, 0), (7, 0), (8, 0), (9, 0), (10, 0), (11, 0), (12, 0), (1, 0), (2, 0), (3, 0)])

with open("in.txt") as f:
    for line in f:
        mn = int(line.split("/",1)[0])
        od.setdefault(mn, 0)
        od[mn] += 1

print(list(od.values()))
[0, 2, 2, 1, 3, 0, 0, 0, 0, 0, 0, 0]

除非你按照上面的逻辑进行操作,否则在实际解析数据时将数据关联起来,那么要计算出哪个月的数量会更加困难。立即创建关联是一种更简单的方法。

如果你有一个列表,元组等值的逻辑是完全相同的:

 for dte in list_of_dates:
        mn = int(dte.split("/",1)[0])
        od.setdefault(mn, 0)
        od[mn] += 1

答案 2 :(得分:1)

为什么不呢:

counter = [0]*12
for m in monthnumbers:
   counter[(m - 4) % 12] += 1

print counter

答案 3 :(得分:0)

以下是更“老派”的做法。它假设您的日期位于CSV文件的第一列,即cols[0]。它验证输入日期,如果日期无效或者比最后一个日期旧,它将引发ValueError异常。如果您的输入跳过一个月或更长时间,它也会处理。

import csv
from datetime import datetime

with open("input.csv", "r") as f_input:
    csv_input = csv.reader(f_input)
    header = next(csv_input)
    last_date = datetime(year=2015, month=4, day=1)
    cur_total = 0
    units_by_month = []

    for cols in csv_input:
        cur_date = datetime.strptime(cols[0], "%m/%d/%Y")

        if cur_date.month == last_date.month:
            cur_total += 1
        elif cur_date < last_date:
            raise ValueError, "Date is older"
        else:
            extra_months = ((cur_date.month + 12 - last_date.month) if cur_date.year - last_date.year else (cur_date.month - last_date.month)) - 1
            units_by_month.extend([cur_total] + ([0] * extra_months))
            last_date = cur_date
            cur_total = 1

    units_by_month.extend([cur_total] + [0] * ((8-len(units_by_month)) if len(units_by_month) < 9 else 0))
    print units_by_month

因此,对于您的输入,它将提供以下输出:

[0, 2, 2, 1, 3, 0, 0, 0, 0, 0]

如果添加了一个额外条目3/1/2016,将显示以下内容:

[0, 2, 2, 1, 3, 0, 0, 0, 0, 0, 0, 1]