【问题标题】:Python Time series: merging daily data in dictionary to weekly dataPython时间序列:将字典中的每日数据合并为每周数据
【发布时间】:2018-06-17 02:28:36
【问题描述】:

我有一本字典如下。

my_dict.keys() = 
dict_keys([20160101, 20160102, 20160103, 20160104, 20160105, 20160106,
       20160107, 20160108, 20160109, 20160110, 20160111, 20160112,
       20160113, 20160114, 20160115, 20160116, 20160117, 20160118,
       20160119, 20160120, 20160121, 20160122, 20160123, 20160124,
       ......    
       20171203, 20171204, 20171213, 20171215, 20171216, 20171217,
       20171218, 20171219, 20171220, 20171221, 20171222, 20171223,
       20171224, 20171225, 20171226, 20171227, 20171228, 20171229,
       20171230, 20171231])

my_dict[20160101] = 
array([[ 0.,  0.,  1.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  2.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.],
       [ 1.,  0.,  0.,  0.,  0.,  2.],
       [ 0.,  0.,  4.,  0.,  0.,  0.]])

所以,您已经注意到我的键表示日期,并且每个日期我都有一个包含 6 x 6 浮点数的数组。在 my_dict 中的每个键中,所有索引都是相同的。

**需要注意的重要一点是 my_dict 并非每天都有。例如,在 20171204 之后,它的 20171213 和 20171215。所以日期可以跳过。

现在我的任务是获取每日数据(不是每一天)到每周数据,并在一周内添加所有值。也就是说,从 2016 年的第一周到 2017 年的最后一周,将一周内的每个值相加,并提供每周数据。另外,由于 2016 年的第一周从 20160103(星期日)开始,我可以忽略 my_dict 中的 20160101 和 20160102 数据以及 2017 年的结束周。你们能帮我解决这个问题吗?提前致谢!

-------编辑--------- 看来我的问题还不够清楚。所以我将提供一个简单的例子。由于我想遵循 pandas datatime week 的标准,所以每周都从星期日开始。所以 2016 年的第一周将是 20160103,20160104,20160105,20160106,20160107,20160108,201601‌​09。

所以我的新字典,weekly_dict[201601]

weekly_dict = {}
weekly_dict[201601] = my_dict[20160103] + my_dict[20160104] + my_dict[20160105] + my_dict[20160106] + my_dict[20160107] + my_dict[20160108] + my_dict[20160109]

然后继续。希望这是有道理的。谢谢!

【问题讨论】:

  • 每周数据是什么意思?你的意思是例如 20171213 将转换为 201750 因为 50 是 2017 年 12/13 的第 50 周?
  • 考虑到星期日是一周的第一天,我想将反映到 2016 年第一周的所有值添加到 20160103,20160104,20160105,20160106,20160107,20160108,20160109 到201601 并用每周数据制作一个新字典。这有帮助吗?

标签: python datetime dictionary timestamp time-series


【解决方案1】:

这可能是熊猫的工作:

import pandas as pd

# First, get a list of keys
date_ints = list(my_dict)
# Turn them into a pandas Series object
date_int_series = pd.Series(date_ints)
# Cast them to a string, then format them into a full datetime-type with the proper
# format specification
datetime_series = pd.to_datetime(date_int_series.astype('str'), format='%Y%m%d')
# Create a dictionary mapping each date integer -> week of the year
date_int_to_week = dict(zip(date_int_series, datetime_series.dt.week))

该字典以my_dict 的每个键为键,其对应的一年中的星期为其值。

编辑:

如果您要查找的是基于星期对原始字典的每个条目求和,您可以执行以下操作:

week_to_date_list = {}
for date_int, week in date_int_to_week.items():
    if week not in week_to_date_list:
        week_to_date_list[week] = []
    week_to_date_list[week].append(date_int)

my_dict_weekly = {}
for week in week_to_date_list:
    arrays_in_week = [my_dict[day_int] for day_int in week_to_date_list[week]]
    my_dict_weekly[week] = reduce(sum, arrays_in_week)

my_dict_weekly 现在应该是一个以一年中的几周为键的字典,然后是对应于该周的所有数组的 sum。如果您使用的是 python 3,则需要从 functools 导入 reduce

【讨论】:

  • 我不明白。这如何将每个字典的值添加到每周值?你介意举个例子吗?
  • 我已经编辑了我的问题。希望这是有道理的。谢谢!
  • 我已经添加了关于如何使用date_int_to_week 字典对原始my_dict 求和的说明。
  • 还有一件事要问。当您设置 date_int_to_week 时,似乎星期一是一周的开始。你怎么能把它改成星期天是一周的开始?
  • ---> 21 arrays_in_week = [my_dict[day_int] for day_int in week_to_date_list[week]] IndexError: list index out of range
【解决方案2】:

如果我确实很好地理解了您的问题,我认为您可以使用datetime 模块中的datetimetimedelta 来解决它,例如这个例子:

from datetime import datetime, timedelta

def get_days_of_week(year, week=1):
    # number of the days
    days = {'Monday': 1, 'Tuesday': 2, 'Wednesday': 3, 
            'Thursday': 4, 'Friday': 5, 'Saturday': 6, 'Sunday': 7}
    # construct the datetime object with the year and the desired week
    a = datetime.strptime('{0}'.format(year), '%Y') + timedelta(days=7*(week-1))
    # Every week should start by Sunday .. So escaping days untill the first Sunday
    a += timedelta(days=7-days.get(a.strftime('%A'), 0))
    for k in range(0, 7):
        yield (a + timedelta(days=k)).strftime('%Y%m%d')

days = list(get_days_of_week(2016, week=1))
print('2016 / week = 1:', days)

days = list(get_days_of_week(2016, week=22))
print('2016 / week = 22:', days)

输出:

2016 / week = 1: 
 ['20160103',
 '20160104',
 '20160105',
 '20160106',
 '20160107',
 '20160108',
 '20160109']

2016 / week = 22: 
 ['20160529',
 '20160530',
 '20160531',
 '20160601',
 '20160602',
 '20160603',
 '20160604']

编辑:

根据您上次的编辑,此代码可能满足您的需求:

from datetime import datetime, timedelta

def get_days_of_week(data):
    # number of the days
    days = {'Monday': 1, 'Tuesday': 2, 'Wednesday': 3,
            'Thursday': 4, 'Friday': 5, 'Saturday': 6, 'Sunday': 7}
    date = datetime.strptime('{}'.format(data), '%Y%m%d')
    # get week number
    week = int(date.strftime('%U'))
    # get year
    year = date.strftime('%Y')
    # construct the datetime object with the year and the desired week
    a = datetime.strptime(year, '%Y') + timedelta(days=7*week)
    # Every week should start by Synday .. So escaping days untill the first Sunday
    a += timedelta(days=7-days.get(a.strftime('%A'), 0))

    return {int(str(data)[:-2]): [int((a + timedelta(days=k)).strftime('%Y%m%d')) for k in range(0, 7)]}

week_dict = {}
week_dict.update(get_days_of_week(20160101))
week_dict.update(get_days_of_week(20160623))
print(week_dict[201601])
print(week_dict[201606])

print(week_dict)

输出:

[20160103, 20160104, 20160105, 20160106, 20160107, 20160108, 20160109]
[20160626, 20160627, 20160628, 20160629, 20160630, 20160701, 20160702]
{ 201601: [ 20160103,
            20160104,
            20160105,
            20160106,
            20160107,
            20160108,
            20160109],
  201606: [ 20160626,
            20160627,
            20160628,
            20160629,
            20160630,
            20160701,
            20160702]}

【讨论】:

  • 我编辑了我的问题。希望它对你有意义!谢谢
猜你喜欢
  • 2014-07-17
  • 1970-01-01
  • 2020-07-06
  • 2021-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-23
  • 2022-09-23
相关资源
最近更新 更多