如何将 `pandas.DataFrame` 与小时列融为一体并将它们划分为 15 分钟的间隔
How to melt `pandas.DataFrame` with hour columns and divide them on 15 minutes intervals
我有一个 DataFrame
像这样的东西:
data = [['2019-01-01', .1, .2],
['2019-01-02', .5, .3],
['2019-01-03', .2, .4]]
df = pd.DataFrame(data, columns=['date', 'hour01', 'hour02'])
date hour01 hour02
0 2019-01-01 0.1 0.2
1 2019-01-02 0.5 0.3
2 2019-01-03 0.2 0.4
如何融化它以便我得到适当的 15 分钟间隔?像这样:
timestamp value
0 2019-01-01 00:00:00 0.1
1 2019-01-01 00:15:00 0.1
2 2019-01-01 00:30:00 0.1
3 2019-01-01 00:45:00 0.1
4 2019-01-01 01:00:00 0.2
5 2019-01-01 01:15:00 0.2
6 2019-01-01 01:30:00 0.2
7 2019-01-01 01:45:00 0.2
...
16 2019-01-03 00:00:00 0.2
17 2019-01-03 00:15:00 0.2
18 2019-01-03 00:30:00 0.2
19 2019-01-03 00:45:00 0.2
20 2019-01-03 01:00:00 0.4
21 2019-01-03 01:15:00 0.4
22 2019-01-03 01:30:00 0.4
23 2019-01-03 01:45:00 0.4
编辑
df.melt(id_vars=['timestamp'], value_vars=['hour_{}'.format(str(x).zfill(2)) for x in range(1, 24)])
给我这个:
27 2017-01-28 hour_01 34.90
28 2017-01-29 hour_01 36.04
29 2017-01-30 hour_01 36.51
... ... ...
16760 2018-12-02 hour_23 51.50
16761 2018-12-03 hour_23 54.00
16762 2018-12-04 hour_23 53.87
从这里到哪里去?
也许你也可以从 melt
开始,但除非出于某种原因需要使用 melt
,否则你可以通过以下方式获得它:
- 将
'date'
设为 datetime
列(如果还没有的话)。
- 使用
groupby
和 apply
您可以使用 pandas date_range and spanning the hourly values using numpy repeat. 为所有时间间隔生成时间戳
- 终于重置索引了。
翻译成代码是:
df['date'] = pd.to_datetime(df['date'])
ddf = df.groupby('date').apply(lambda row : pd.DataFrame(
{'timestamp' : pd.date_range(row['date'].iloc[0], periods=4*len(df.columns[1:]), freq='15T'),
'value' : np.repeat(np.array([row[col].iloc[0] for col in df.columns[1:]]), 4)}))
ddf.reset_index(inplace=True, drop=True)
使用您的起始数据框,ddf
是:
timestamp value
0 2019-01-01 00:00:00 0.1
1 2019-01-01 00:15:00 0.1
2 2019-01-01 00:30:00 0.1
3 2019-01-01 00:45:00 0.1
4 2019-01-01 01:00:00 0.2
5 2019-01-01 01:15:00 0.2
6 2019-01-01 01:30:00 0.2
7 2019-01-01 01:45:00 0.2
8 2019-01-02 00:00:00 0.5
9 2019-01-02 00:15:00 0.5
10 2019-01-02 00:30:00 0.5
11 2019-01-02 00:45:00 0.5
12 2019-01-02 01:00:00 0.3
13 2019-01-02 01:15:00 0.3
14 2019-01-02 01:30:00 0.3
15 2019-01-02 01:45:00 0.3
16 2019-01-03 00:00:00 0.2
17 2019-01-03 00:15:00 0.2
18 2019-01-03 00:30:00 0.2
19 2019-01-03 00:45:00 0.2
20 2019-01-03 01:00:00 0.4
21 2019-01-03 01:15:00 0.4
22 2019-01-03 01:30:00 0.4
23 2019-01-03 01:45:00 0.4
此代码将自动选择 'date'
之后的列数,假设它们都是 'hour'
列。如果数据框中混合了其他列,则应从 df.columns[1:]
.
中过滤掉它们
基于melt
、set_index
和ffill
的解决方案:
df = df.melt(id_vars=['date'], var_name='hour')
df['timestamp'] = pd.to_datetime(df['date']) + pd.to_timedelta(df['hour'].str[4:].astype(int) - 1, unit='h')
df = df.set_index(pd.DatetimeIndex(df['timestamp']))
df = df.drop(columns=['timestamp', 'date', 'hour'])
df = df.resample('15T').ffill()
df = df.reset_index()
结果:
timestamp value
0 2019-01-01 00:00:00 0.1
1 2019-01-01 00:15:00 0.1
2 2019-01-01 00:30:00 0.1
3 2019-01-01 00:45:00 0.1
4 2019-01-01 01:00:00 0.2
.. ... ...
192 2019-01-03 00:00:00 0.2
193 2019-01-03 00:15:00 0.2
194 2019-01-03 00:30:00 0.2
195 2019-01-03 00:45:00 0.2
196 2019-01-03 01:00:00 0.4
我有一个 DataFrame
像这样的东西:
data = [['2019-01-01', .1, .2],
['2019-01-02', .5, .3],
['2019-01-03', .2, .4]]
df = pd.DataFrame(data, columns=['date', 'hour01', 'hour02'])
date hour01 hour02
0 2019-01-01 0.1 0.2
1 2019-01-02 0.5 0.3
2 2019-01-03 0.2 0.4
如何融化它以便我得到适当的 15 分钟间隔?像这样:
timestamp value
0 2019-01-01 00:00:00 0.1
1 2019-01-01 00:15:00 0.1
2 2019-01-01 00:30:00 0.1
3 2019-01-01 00:45:00 0.1
4 2019-01-01 01:00:00 0.2
5 2019-01-01 01:15:00 0.2
6 2019-01-01 01:30:00 0.2
7 2019-01-01 01:45:00 0.2
...
16 2019-01-03 00:00:00 0.2
17 2019-01-03 00:15:00 0.2
18 2019-01-03 00:30:00 0.2
19 2019-01-03 00:45:00 0.2
20 2019-01-03 01:00:00 0.4
21 2019-01-03 01:15:00 0.4
22 2019-01-03 01:30:00 0.4
23 2019-01-03 01:45:00 0.4
编辑
df.melt(id_vars=['timestamp'], value_vars=['hour_{}'.format(str(x).zfill(2)) for x in range(1, 24)])
给我这个:
27 2017-01-28 hour_01 34.90
28 2017-01-29 hour_01 36.04
29 2017-01-30 hour_01 36.51
... ... ...
16760 2018-12-02 hour_23 51.50
16761 2018-12-03 hour_23 54.00
16762 2018-12-04 hour_23 53.87
从这里到哪里去?
也许你也可以从 melt
开始,但除非出于某种原因需要使用 melt
,否则你可以通过以下方式获得它:
- 将
'date'
设为datetime
列(如果还没有的话)。 - 使用
groupby
和apply
您可以使用 pandas date_range and spanning the hourly values using numpy repeat. 为所有时间间隔生成时间戳
- 终于重置索引了。
翻译成代码是:
df['date'] = pd.to_datetime(df['date'])
ddf = df.groupby('date').apply(lambda row : pd.DataFrame(
{'timestamp' : pd.date_range(row['date'].iloc[0], periods=4*len(df.columns[1:]), freq='15T'),
'value' : np.repeat(np.array([row[col].iloc[0] for col in df.columns[1:]]), 4)}))
ddf.reset_index(inplace=True, drop=True)
使用您的起始数据框,ddf
是:
timestamp value
0 2019-01-01 00:00:00 0.1
1 2019-01-01 00:15:00 0.1
2 2019-01-01 00:30:00 0.1
3 2019-01-01 00:45:00 0.1
4 2019-01-01 01:00:00 0.2
5 2019-01-01 01:15:00 0.2
6 2019-01-01 01:30:00 0.2
7 2019-01-01 01:45:00 0.2
8 2019-01-02 00:00:00 0.5
9 2019-01-02 00:15:00 0.5
10 2019-01-02 00:30:00 0.5
11 2019-01-02 00:45:00 0.5
12 2019-01-02 01:00:00 0.3
13 2019-01-02 01:15:00 0.3
14 2019-01-02 01:30:00 0.3
15 2019-01-02 01:45:00 0.3
16 2019-01-03 00:00:00 0.2
17 2019-01-03 00:15:00 0.2
18 2019-01-03 00:30:00 0.2
19 2019-01-03 00:45:00 0.2
20 2019-01-03 01:00:00 0.4
21 2019-01-03 01:15:00 0.4
22 2019-01-03 01:30:00 0.4
23 2019-01-03 01:45:00 0.4
此代码将自动选择 'date'
之后的列数,假设它们都是 'hour'
列。如果数据框中混合了其他列,则应从 df.columns[1:]
.
基于melt
、set_index
和ffill
的解决方案:
df = df.melt(id_vars=['date'], var_name='hour')
df['timestamp'] = pd.to_datetime(df['date']) + pd.to_timedelta(df['hour'].str[4:].astype(int) - 1, unit='h')
df = df.set_index(pd.DatetimeIndex(df['timestamp']))
df = df.drop(columns=['timestamp', 'date', 'hour'])
df = df.resample('15T').ffill()
df = df.reset_index()
结果:
timestamp value
0 2019-01-01 00:00:00 0.1
1 2019-01-01 00:15:00 0.1
2 2019-01-01 00:30:00 0.1
3 2019-01-01 00:45:00 0.1
4 2019-01-01 01:00:00 0.2
.. ... ...
192 2019-01-03 00:00:00 0.2
193 2019-01-03 00:15:00 0.2
194 2019-01-03 00:30:00 0.2
195 2019-01-03 00:45:00 0.2
196 2019-01-03 01:00:00 0.4