【问题标题】:Selecting datetime range in MultiIndexed dataframe in Pandas在 Pandas 的 MultiIndexed 数据框中选择日期时间范围
【发布时间】:2022-01-23 20:20:44
【问题描述】:

问题来了:

我想选择 df1 中每个 index1 的数据框(例如 df3),使其位于 df2 中的 d_reachd_start 之间,

下面是生成样本的代码:

import numpy as np
import pandas as pd
import datetime
from datetime import timedelta

index1 = pd.date_range(datetime.datetime(2021, 1, 1, 1, 1), periods = 1000, freq = "3min")

df1 = pd.DataFrame(np.random.random(1000), index = index1, columns = ['r'])

d_start = pd.date_range(datetime.datetime(2021, 1, 1, 1, 1), periods = 500, freq = "5min")

d_reach = d_start + timedelta(seconds = np.random.randint(low = 4, high = 6))

value = {'id3': np.tile([0,1], 250)}

df2 = pd.DataFrame(value, index = [d_start,d_reach])

df2.index.names = ['d_start','d_reach']

df2 被多重索引。

df3 的预期输出应该是:

2021-01-01 01:07:00     0.011026

2021-01-01 01:10:00     0.423813
...

这里是index1 in df1 2021-01-01 01:07:00 >= 2021-01-01 01:06:05 这是df2 中的d_reach 之一 和df1 中的下一个index1 2021-01-01 01:10:00 < 2021-01-01 01:11:00df2 中的下一个d_start

下面是我试过但失败的代码:

df = pd.DataFrame()
for i in df1.index:
    df = df.append(df1.loc[i])
    for idx1, idx2 in zip(df2.index.get_level_values(0).tolist(), 
    df2.index.get_level_values(1).tolist())
    if i >= idx1 and i <= idx2

非常感谢任何关于在 Python 中查找 df3 的建议。谢谢!

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    我想选择 df1 中每个 index1 的数据帧(例如 df3)在 df2 中的 d_reach 和 d_start 之间的范围内,

    这是一种交叉加入的方法,然后找到匹配项并将它们过滤掉:

    mdf = pd.merge(df1.reset_index(), df2.reset_index() , how='cross', on=None)
    result = mdf.loc[mdf['index'].between(mdf['d_start'], mdf['d_reach']),['index','r']].set_index('index')
    print(result.head())
    

    输出:

    >>>
                                r
    index                        
    2021-01-01 01:01:00  0.415163
    2021-01-01 01:16:00  0.729592
    2021-01-01 01:31:00  0.411244
    2021-01-01 01:46:00  0.524753
    2021-01-01 02:01:00  0.105035
    

    不过,这将是内存密集型的,另一种方法是将数据帧加载到内存数据库中,然后根据条件将它们连接起来,然后将结果加载回结果数据帧,你会发现很多样本在线方法。

    【讨论】:

    • 感谢您的快速回答!结果不正确,因为它应该以“2021-01-01 01:07:00”而不是“2021-01-01 01:01:00”开头。我得到了'MergeError:没有要执行合并的通用列。合并选项:left_on=None、right_on=None、left_index=False、right_index=False'
    • @JianXu 你交叉加入了吗? (`how='cross',`) 以及为什么它应该从 01:07 开始?
    • 是的,我使用 how = 'cross'。您可以从我的问题中找到详细信息,因为“2021-01-01 01:07:00 >= 2021-01-01 01:06:05 这是 df2 中的 d_reach 和 df1 2021-01 中的下一个 index1 之一-01 01:10:00
    • 虽然 'r' 或 'id3' 值是随机生成的,但 DatetimeIndex 是固定的。所以它必须以'2021-01-01 01:07:00'开始
    • 好的,对不起,但这就是你所要求的:I want to select the dataframe (say, df3) with each index1 in df1 to be in the range between d_reach and d_start in df2,
    猜你喜欢
    • 2021-05-09
    • 2013-03-27
    • 1970-01-01
    • 1970-01-01
    • 2016-05-08
    • 1970-01-01
    • 2012-04-12
    • 1970-01-01
    相关资源
    最近更新 更多