【问题标题】:pandas long to wide from datetime index大熊猫从日期时间索引长到宽
【发布时间】:2020-08-06 23:39:21
【问题描述】:

我有一个带有日期索引和 2 列的数据框:

            val     week
2015-01-02  16729   1
2015-01-09  16225   2
2015-01-16  15250   3
2015-01-23  15690   4
2015-01-30  16025   5
...         ...     ...
2020-03-20  16417   12
2020-03-27  15481   13
2020-04-03  14216   14
2020-04-10  13113   15
2020-04-17  12825   16

我想做的是按年份进行透视或分组,然后将月份和星期作为索引。

            2015    ...    2020
01-1        16729   ...    ...
01-2        16225   ...    ...
01-3        15250   ...    ...
01-4        15690   ...    ...
01-5        16025   ...    ...
...         ...     ...    ...
03-12       ...     ...    16417
03-13       ...     ...    15481
04-14       ...     ...    14216
04-15       ...     ...    13113
04-16       ...     ...    12825

最好只保留月份和日期作为索引,但由于它是每周频率,因此一周中的实际日期在不同年份会有所不同。如果有办法将日期汇总起来,那么日期是否准确并不重要。

            2015    ...    2020
01-02       16729   ...    ...
01-09       16225   ...    ...
01-16       15250   ...    ...
01-23       15690   ...    ...
01-30       16025   ...    ...
...         ...     ...    ...
03-20       ...     ...    16417
03-27       ...     ...    15481
04-03       ...     ...    14216
04-10       ...     ...    13113
04-17       ...     ...    12825

我尝试过使用pd.Groupergroupby 的变体,但我似乎无法正确使用。我也愿意接受其他关于如何安排这一点的建议,因为我们的想法是每年在同一个折线图上绘制成一条单独的线。

【问题讨论】:

  • 你试过pivot_table吗?我认为像pd.pivot_table(df, values='val', index=df.index.strftime('%m-%W'), columns=df.index.year) 这样的东西应该朝着你预期的输出方向发展。
  • @MrFuppes 确实有效,太棒了。我不认为您可以想出一种方法来匹配最近的日期而不是按周数汇总?这会更好,因为我在返回的帧中散布了 NaN。
  • 匹配到最近的日期是什么意思?您的日期似乎都在星期五,您的意思是它们都必须是星期五吗?如果是这样,我猜你想匹配到周五的同一周的周一到周四,但是周六/周日呢?无论如何,可以使用调整后的日期创建一个临时列,并将其用于索引。当然,您需要为pivot_table 识别aggfunc 来处理重复项。
  • @r.ook 对不起,我应该更具体。当我使用这种方法执行此操作时,会重复一些周但有不同的月份(即 6-26、7-26),然后在重复周的单元格中存在 NaN 值,而在另一个重复周中存在值,反之亦然反之亦然。因此,6-26 可能具有 2015、2016、2018 年的值,但 7-26 具有 2017 年和 2019 年的值。如果这是有道理的。不知道如何最好地处理这个
  • 当然一个日历周可以在两个月之间;所以你可能想要做的是在枢轴之后groupby week

标签: python pandas dataframe datetime


【解决方案1】:

在所有的 cmets 之后,似乎是时候编写一些代码了。有点hacky,但也许这会对你有所帮助:

import numpy as np
import pandas as pd

# example df with some random values.
df = pd.DataFrame({'t': ['2015-01-02','2015-01-03','2015-01-16','2015-01-23','2015-01-30', '2020-01-01'],
                   'val': [16729, 16225, 15250, 15690, 16025, 999],
                   'week': [1, 2, 3, 4, 5, 1]})
df['t'] = pd.to_datetime(df['t'])

# pivot to get years as columns
df1 = pd.pivot_table(df, values='val', columns=df['t'].dt.year, index=df['t'])

# create a new column "date" for later on... cast to datetime object for now
df1['date'] = pd.to_datetime(df1.index.date)

# sum the values for every week and drop the original "t" (datetime) column
df2 = df1.groupby(df1.index.week).resample('W-Mon', on='date').sum().reset_index().sort_values(by='date').drop(columns=['t'])

# drop all rows that only hold zeros
df2 = df2.loc[~np.isclose(df2.loc[:, df2.columns != 'date'], 0)]

# finally, format the datetime column to string as desired
df2['month-week'] = df2['date'].dt.strftime('%m-%W')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-12
    • 2019-06-27
    • 2013-07-20
    • 2017-02-09
    • 2017-05-22
    • 1970-01-01
    相关资源
    最近更新 更多