假设我从数据库中提取了以下数据:
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)
在熊猫中执行此操作的有效方法是什么(数据集有数十万行)。
您可以执行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()
)