【问题标题】:Populating each calendar month with a specific incrementing pattern使用特定的递增模式填充每个日历月
【发布时间】:2023-02-15 18:02:43
【问题描述】:

给定一个按时间序列索引的熊猫DataFrame,例如

import pandas as pd
import numpy as np

index = pd.date_range('2023-01-01', '2023-12-31', freq='1D')
pd.DataFrame({'a' : np.random.randint(0, 10, len(index))}, index=index)
            a
2023-01-01  3
2023-01-02  2
2023-01-03  1
2023-01-04  3
2023-01-05  8
...        ..
2023-12-27  2
2023-12-28  2
2023-12-29  0
2023-12-30  1
2023-12-31  7

如何在每个日历月内添加一个填充有递增模式的新列?例如。b: day_of_month / days_in_month,

            a         b
2023-01-01  0  0.032258
2023-01-02  5  0.064516
2023-01-03  2  0.096774
2023-01-04  7  0.129032
2023-01-05  4  0.161290
...        ..       ...
2023-12-27  6  0.870968
2023-12-28  5  0.903226
2023-12-29  8  0.935484
2023-12-30  2  0.967742
2023-12-31  9  1.000000

这样就创建了以下模式:

【问题讨论】:

  • 我遇到过很多关于在固定间隔内使用递增模式填充 DataFrame 列的问题和答案,但没有一个解决日历月的不同长度或 DatetimeIndex 指标。

标签: python pandas


【解决方案1】:

这有点复杂,但这可以使用以下过程来完成:

  1. 将月中的某天分配给新列。
    df['b'] = df.index.day
    
                a   b
    2023-01-01  3   1
    2023-01-02  0   2
    2023-01-03  0   3
    2023-01-04  8   4
    2023-01-05  2   5
    ...        ..  ..
    2023-12-27  2  27
    2023-12-28  1  28
    2023-12-29  3  29
    2023-12-30  1  30
    2023-12-31  4  31
    
    1. 将每月重新抽样的最后一天分配给第三列。这将确保索引的统一性。
    df['c'] = df.resample('1M').b.last().copy()
    
                a   b     c
    2023-01-01  3   1   NaN
    2023-01-02  0   2   NaN
    2023-01-03  0   3   NaN
    2023-01-04  8   4   NaN
    2023-01-05  2   5   NaN
    ...        ..  ..   ...
    2023-12-27  2  27   NaN
    2023-12-28  1  28   NaN
    2023-12-29  3  29   NaN
    2023-12-30  1  30   NaN
    2023-12-31  4  31  31.0
    
    1. 回填和应用操作(在要求的情况下,除法)。
    2. (可选)处理帮助列 c
                a         b
    2023-01-01  3  0.032258
    2023-01-02  0  0.064516
    2023-01-03  0  0.096774
    2023-01-04  8  0.129032
    2023-01-05  2  0.161290
    ...        ..       ...
    2023-12-27  2  0.870968
    2023-12-28  1  0.903226
    2023-12-29  3  0.935484
    2023-12-30  1  0.967742
    2023-12-31  4  1.000000
    

    一个完整的例子,从问题中扩展代码:

    import pandas as pd
    import numpy as np
    
    index = pd.date_range('2023-01-01', '2023-12-31', freq='1D')
    df = pd.DataFrame({'a' : np.random.randint(0, 10, len(index))}, index=index)
    
    df['b'] = df.index.day
    df['c'] = df.resample('1M').b.last().copy()
    df.c = df.c.bfill()
    df.b /= df.c
    df.drop(['c'], inplace=True, axis=1)
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 2019-11-13
    • 2017-10-19
    • 2019-01-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多