【问题标题】:How to get elements from a dataframe given dates in another dataframe如何从另一个数据框中给定日期的数据框中获取元素
【发布时间】:2021-08-27 22:07:21
【问题描述】:

我有一个数据框中的日期列表,以及另一个包含一天中百分比变化的数据框。

带有日期的示例数据框 (df_date):

df_test = pd.DataFrame({
'Specific_date': {0: '2016-01-10', 1: '2016-01-12', 2: '2016-01-13', 3: '2016-01-19'}})

df_test['Specific_date'] = pd.to_datetime(df_test['Specific_date'])

百分比变化数据框 (df_percent):

Hour        9am     10am    11am    12pm    1pm     2pm     3pm     4pm
Date                                
2016-01-05  20.6475 20.5900 20.4225 20.6275 20.1600 19.6500 19.6250 19.4100
2016-01-06  21.3550 20.8675 20.6100 20.6525 20.8900 21.0125 21.0600 20.5125
2016-01-07  23.0075 22.7975 23.0050 23.5975 24.4675 25.2450 25.1600 24.9575
2016-01-08  22.9125 23.2400 23.8575 23.9475 24.0425 24.4000 25.7950 26.7625
2016-01-11  25.7500 25.9100 25.8800 25.9325 26.7650 26.4025 24.9425 24.2725
2016-01-12  22.5500 22.6900 23.2700 23.2550 23.1425 22.8175 22.2925 22.4175
2016-01-13  21.8175 22.6200 22.5225 23.2675 23.9650 25.0500 24.9575 25.1100
2016-01-14  25.4600 25.0050 24.2875 24.2050 24.2850 23.7800 23.6775 23.9575
2016-01-15  28.3200 28.5925 27.8400 28.8900 29.2925 28.4225 27.6525 27.1525
2016-01-19  26.1625 26.3400 26.0725 26.2550 26.3275 26.9225 26.5725 26.0075

我正在尝试使用 df_test 中的这些日期来过滤掉示例数据框中的日期(数据每天从 2016 年运行到 2020 年)。

逻辑:我想获取df_date 中日期 (T=0) 的值,以及日期前 3、2 和 1 天的值 (T-3、T-2、T-1 ) 和 1、2 和 3 天后。 (T+1, T+2, T+3),将它们附加到新的数据帧,并检查字典中的下一个日期以将关联的值附加到这些数据帧。

我曾考虑尝试为每个 T 创建一个新的数据框,并假设我会这样做,伪逻辑英语代码会看起来像这样。

Tm3, Tm2, Tm1, T0, Tp1, Tp2, Tp3 = pd.DataFrame()
for date in df_percent['Date']:
   if df_percent['Date'] is in df_date['Specific_date']:
       Tm3 = df_percent['Date'] - BDay(3)
       Tm2 = df_percent['Date'] - BDay(2)
       Tm1 = df_percent['Date'] - BDay(1)
       T0 = df_percent['Date']
       Tp1 = df_percent['Date'] + BDay(1)
       Tp2 = df_percent['Date'] + BDay(2)
       Tp3 = df_percent['Date'] + BDay(3)

我不认为这是正确的方法,或者我使用了错误的逻辑,但我无法从我现在所拥有的内容中产生任何富有成效的东西,即我上面所拥有的弗兰肯斯坦版本。

df_test 中元素的 Tm3 数据帧的预期输出样本:

Hour        9am     10am    11am    12pm    1pm     2pm     3pm     4pm
Date
2016-01-06  21.3550 20.8675 20.6100 20.6525 20.8900 21.0125 21.0600 20.5125
2016-01-07  23.0075 22.7975 23.0050 23.5975 24.4675 25.2450 25.1600 24.9575
2016-01-08  22.9125 23.2400 23.8575 23.9475 24.0425 24.4000 25.7950 26.7625
2016-01-13  21.8175 22.6200 22.5225 23.2675 23.9650 25.0500 24.9575 25.1100

任何帮助将不胜感激:)

已编辑:

编辑#2:

编辑#3:

编辑#4:

【问题讨论】:

    标签: python pandas dataframe numpy


    【解决方案1】:

    您的数据看起来像金融市场数据。金融市场并非每个工作日都开放(有交易大厅假期),因此您不能使用BDay。相反,最好在您的df_percent 中按顺序标记每一天,这样第 0 天是 2016-01-05,第 1 天是 2016-01-06,等等。这样您可以轻松参考之前或之后的 n 个交易日。

    # Assign a sequential number to each trading day
    df_melt_test_percent = df_melt_test_percent.sort_index().assign(DayNumber=lambda x: range(len(x)))
    
    # Find the indices of the FOMC_dates
    tmp = pd.merge(
        df_FOMC_dates, df_melt_test_percent[['DayNumber']],
        left_on='FOMC_dates', right_index=True
    )
    
    # For each row, get the FOMC_dates ± 3 days
    tmp['delta'] = tmp.apply(lambda _: range(-3, 4), axis=1)
    
    tmp = tmp.explode('delta')
    tmp['DayNumber'] += tmp['delta']
    
    # Assemble the result
    result = pd.merge(tmp, df_melt_test_percent, on='DayNumber')
    

    结果:

    FOMC_dates DayNumber delta     9am    10am    11am    12pm     1pm     2pm     3pm     4pm
    2016-01-12         2    -3 23.0075 22.7975 23.0050 23.5975 24.4675 25.2450 25.1600 24.9575
    2016-01-12         3    -2 22.9125 23.2400 23.8575 23.9475 24.0425 24.4000 25.7950 26.7625
    2016-01-13         3    -3 22.9125 23.2400 23.8575 23.9475 24.0425 24.4000 25.7950 26.7625
    2016-01-12         4    -1 25.7500 25.9100 25.8800 25.9325 26.7650 26.4025 24.9425 24.2725
    2016-01-13         4    -2 25.7500 25.9100 25.8800 25.9325 26.7650 26.4025 24.9425 24.2725
    2016-01-12         5     0 22.5500 22.6900 23.2700 23.2550 23.1425 22.8175 22.2925 22.4175
    2016-01-13         5    -1 22.5500 22.6900 23.2700 23.2550 23.1425 22.8175 22.2925 22.4175
    2016-01-12         6     1 21.8175 22.6200 22.5225 23.2675 23.9650 25.0500 24.9575 25.1100
    2016-01-13         6     0 21.8175 22.6200 22.5225 23.2675 23.9650 25.0500 24.9575 25.1100
    2016-01-19         6    -3 21.8175 22.6200 22.5225 23.2675 23.9650 25.0500 24.9575 25.1100
    2016-01-12         7     2 25.4600 25.0050 24.2875 24.2050 24.2850 23.7800 23.6775 23.9575
    2016-01-13         7     1 25.4600 25.0050 24.2875 24.2050 24.2850 23.7800 23.6775 23.9575
    2016-01-19         7    -2 25.4600 25.0050 24.2875 24.2050 24.2850 23.7800 23.6775 23.9575
    2016-01-12         8     3 28.3200 28.5925 27.8400 28.8900 29.2925 28.4225 27.6525 27.1525
    2016-01-13         8     2 28.3200 28.5925 27.8400 28.8900 29.2925 28.4225 27.6525 27.1525
    2016-01-19         8    -1 28.3200 28.5925 27.8400 28.8900 29.2925 28.4225 27.6525 27.1525
    2016-01-13         9     3 26.1625 26.3400 26.0725 26.2550 26.3275 26.9225 26.5725 26.0075
    2016-01-19         9     0 26.1625 26.3400 26.0725 26.2550 26.3275 26.9225 26.5725 26.0075
    

    带有delta = 0 的行是您原来的FOMC_dates。您可以删除不需要的列并将其旋转到您喜欢的形状。

    【讨论】:

    • 嗨,首先,非常感谢您的解释!不过,我在尝试实现它时遇到了困难,并且收到了来自reset_index() 函数的错误:ValueError: cannot insert level_0, already exists。我尝试了drop = Truedroplevel(0),但它没有改变任何输出。
    • 重新初始化百分比数据框,改为reset_index(drop=True)
    • 在 OP 中发布错误
    • 我可能发现了问题所在。 df_percent 中的日期列不是实际的列名,因为它们被转换为 pd.to_datetime
    • 发布了数据框的示例。不过,不确定如何将这些列转换回来,因为它们只是标签。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-21
    相关资源
    最近更新 更多