【问题标题】:Making a list based off of list of months in Python根据 Python 中的月份列表制作列表
【发布时间】:2015-11-11 18:29:03
【问题描述】:

我正在使用 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)

但这并不能说明在这一轮中我的数据是从 5 月开始的,所以我需要在第一个插槽中输入一个零。

【问题讨论】:

  • 5 月份只有两个条目。

标签: python list for-loop count append


【解决方案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

【讨论】:

  • 感谢您的回答。不过我很困惑,您的 in.text 文件中有什么?
  • @jenryb,我只是使用了您问题中的日期,它们来自哪里无关紧要,逻辑完全相同,只需遍历日期并应用它
  • 谢谢。这很有效,并减少了我之前尝试过的大量不必要的计数代码。
【解决方案2】:

您可以使用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)])]

【讨论】:

    【解决方案3】:

    为什么不只是:

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

    【讨论】:

      【解决方案4】:

      以下是更“老派”的方法。它假定您的日期位于 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]
      

      【讨论】:

        猜你喜欢
        • 2019-07-17
        • 2018-06-21
        • 1970-01-01
        • 2021-11-26
        • 2018-05-06
        • 1970-01-01
        • 1970-01-01
        • 2021-06-21
        • 1970-01-01
        相关资源
        最近更新 更多