我如何将具有日期范围的行转换为每个日期都在愤怒范围内的行?

问题描述 投票:0回答:1

假设我从数据库中提取了以下数据:

data = [ 
    {'db_id': 1, 'start': '2020-02-02', 'end': '2020-02-05'},
    {'db_id': 2, 'start': '2020-02-04', 'end': '2020-02-06'},
    {'db_id': 3, 'start': '2020-02-02', 'end': '2020-02-04'}
]
df = pd.DataFrame(data)

我想将每个date / db_id组合都转换为一行,包括开始和结束日期。因此,我想结束下面的DataFrame:

result_data = [
    {'db_id': 1, 'date': '2020-02-02'},
    {'db_id': 1, 'date': '2020-02-03'},
    {'db_id': 1, 'date': '2020-02-04'},
    {'db_id': 1, 'date': '2020-02-05'},
    {'db_id': 2, 'date': '2020-02-04'},
    {'db_id': 2, 'date': '2020-02-05'},
    {'db_id': 2, 'date': '2020-02-06'},
    {'db_id': 3, 'date': '2020-02-02'},
    {'db_id': 3, 'date': '2020-02-03'},
    {'db_id': 3, 'date': '2020-02-04'},
]

result_df = pd.DataFrame(result_data)

在熊猫中执行此操作的有效方法是什么(数据集有数十万行)。

python pandas dataframe
1个回答
0
投票

您可以执行resample,但首先需要确保您的日期为datetime类型:

df['start'], df['end'] = pd.to_datetime(df['start']), pd.to_datetime(df['end'])

(df.melt(id_vars='db_id', value_name='date')
   .set_index('date')
   .groupby('db_id')['variable'].resample('D').ffill()
   .reset_index()
   .drop('variable',axis=1)
)

输出:

   db_id       date
0      1 2020-02-02
1      1 2020-02-03
2      1 2020-02-04
3      1 2020-02-05
4      2 2020-02-04
5      2 2020-02-05
6      2 2020-02-06
7      3 2020-02-02
8      3 2020-02-03

或者您也可以进行简单的for循环:

pd.concat(pd.DataFrame({'db_id':x['db_id'], 
                        'date':pd.date_range(x['start'], x['end'], freq='D')}
                        ) 
          for _, x in df.iterrows()
         )
© www.soinside.com 2019 - 2024. All rights reserved.