【问题标题】:Replicate a row n times with different index in a pandas dataframe在 pandas 数据框中使用不同的索引复制一行 n 次
【发布时间】:2021-02-19 17:56:45
【问题描述】:

我有一个时间序列数据集 1,步长为 1 小时:

我还有另一个时间序列数据集 2,步长为 15 分钟:

我希望第一个数据集与第二个数据集具有相同的时间步长(15 分钟),方法是将每行复制 4 次并将时间索引更改为与第二个数据集相同。

有没有没有任何错误的简单方法?

【问题讨论】:

  • 是的,使用 np.repeat(4) 并使用 timedelta() 添加时间。如果您需要帮助,您需要以明文形式共享数据。如果您共享图像,没有人可以重现问题

标签: python pandas dataframe time-series


【解决方案1】:

选项 1:使用 pd.Index.repeatpd.Timedelta()

import pandas as pd
import numpy as np
pd.set_option('display.max_columns', 200)
df = pd.DataFrame({
    'timestamp':['2019-11-25T00:00:00','2019-11-25T01:00:00','2019-11-25T02:00:00','2019-11-25T03:00:00','2019-11-25T04:00:00'],
    'temperature':[8.7,8.8,8.9,8.8,8.8],
    'wind_speed':[11.0,9.0,8.0,7.0,10.0],
    'wind_gust_speed':[24.0,20.0,18.0,18.0,23.0],
    'rain_level':[0.0,0.0,0.0,0.0,0.0],
    'traffic_state':['Fluid']*5,
    'average_flow':[218.1,144.3,110.0,143.8,315.1]
    })

df['timestamp'] = pd.to_datetime(df['timestamp'])


df4 = df.loc[df.index.repeat(4)].reset_index(drop=True)
df4['timestamp'] = df4.apply(lambda x: x.timestamp + pd.Timedelta(minutes=(x.name%4)*15), axis=1)
print (df4)

这个输出将是:

             timestamp  temperature  wind_speed  wind_gust_speed  rain_level  \
0  2019-11-25 00:00:00          8.7        11.0             24.0         0.0   
1  2019-11-25 00:15:00          8.7        11.0             24.0         0.0   
2  2019-11-25 00:30:00          8.7        11.0             24.0         0.0   
3  2019-11-25 00:45:00          8.7        11.0             24.0         0.0   
4  2019-11-25 01:00:00          8.8         9.0             20.0         0.0   
5  2019-11-25 01:15:00          8.8         9.0             20.0         0.0   
6  2019-11-25 01:30:00          8.8         9.0             20.0         0.0   
7  2019-11-25 01:45:00          8.8         9.0             20.0         0.0   
8  2019-11-25 02:00:00          8.9         8.0             18.0         0.0   
9  2019-11-25 02:15:00          8.9         8.0             18.0         0.0   
10 2019-11-25 02:30:00          8.9         8.0             18.0         0.0   
11 2019-11-25 02:45:00          8.9         8.0             18.0         0.0   
12 2019-11-25 03:00:00          8.8         7.0             18.0         0.0   
13 2019-11-25 03:15:00          8.8         7.0             18.0         0.0   
14 2019-11-25 03:30:00          8.8         7.0             18.0         0.0   
15 2019-11-25 03:45:00          8.8         7.0             18.0         0.0   
16 2019-11-25 04:00:00          8.8        10.0             23.0         0.0   
17 2019-11-25 04:15:00          8.8        10.0             23.0         0.0   
18 2019-11-25 04:30:00          8.8        10.0             23.0         0.0   
19 2019-11-25 04:45:00          8.8        10.0             23.0         0.0   

   traffic_state  average_flow  
0          Fluid         218.1  
1          Fluid         218.1  
2          Fluid         218.1  
3          Fluid         218.1  
4          Fluid         144.3  
5          Fluid         144.3  
6          Fluid         144.3  
7          Fluid         144.3  
8          Fluid         110.0  
9          Fluid         110.0  
10         Fluid         110.0  
11         Fluid         110.0  
12         Fluid         143.8  
13         Fluid         143.8  
14         Fluid         143.8  
15         Fluid         143.8  
16         Fluid         315.1  
17         Fluid         315.1  
18         Fluid         315.1  
19         Fluid         315.1  

以下是我在执行 np.repeat 之前尝试解决的其他选项。这些解决了问题,但有局限性。我已经为你解释过了。

选项 2:使用df.asfreq('15min')

我不知道你是否能够快速度过这个难关。您还可以使用df.asfreq('15min') 创建 15 分钟间隔。首先,您需要在 timestamp 上设置索引,因为 df.asfreq() 适用于系列。

这是怎么做的:

import pandas as pd
pd.set_option('display.max_columns', 200)
df = pd.DataFrame({
    'timestamp':['2019-11-25T00:00:00','2019-11-25T01:00:00','2019-11-25T02:00:00','2019-11-25T03:00:00','2019-11-25T04:00:00'],
    'temperature':[8.7,8.8,8.9,8.8,8.8],
    'wind_speed':[11.0,9.0,8.0,7.0,10.0],
    'wind_gust_speed':[24.0,20.0,18.0,18.0,23.0],
    'rain_level':[0.0,0.0,0.0,0.0,0.0],
    'traffic_state':['Fluid']*5,
    'average_flow':[218.1,144.3,110.0,143.8,315.1]
    })

df['timestamp'] = pd.to_datetime(df['timestamp'])
df = df.set_index('timestamp')
df1 = df.asfreq('15min').reset_index().ffill()

print (df1)


             timestamp  temperature  wind_speed  wind_gust_speed  rain_level  \
0  2019-11-25 00:00:00          8.7        11.0             24.0         0.0   
1  2019-11-25 00:15:00          8.7        11.0             24.0         0.0   
2  2019-11-25 00:30:00          8.7        11.0             24.0         0.0   
3  2019-11-25 00:45:00          8.7        11.0             24.0         0.0   
4  2019-11-25 01:00:00          8.8         9.0             20.0         0.0   
5  2019-11-25 01:15:00          8.8         9.0             20.0         0.0   
6  2019-11-25 01:30:00          8.8         9.0             20.0         0.0   
7  2019-11-25 01:45:00          8.8         9.0             20.0         0.0   
8  2019-11-25 02:00:00          8.9         8.0             18.0         0.0   
9  2019-11-25 02:15:00          8.9         8.0             18.0         0.0   
10 2019-11-25 02:30:00          8.9         8.0             18.0         0.0   
11 2019-11-25 02:45:00          8.9         8.0             18.0         0.0   
12 2019-11-25 03:00:00          8.8         7.0             18.0         0.0   
13 2019-11-25 03:15:00          8.8         7.0             18.0         0.0   
14 2019-11-25 03:30:00          8.8         7.0             18.0         0.0   
15 2019-11-25 03:45:00          8.8         7.0             18.0         0.0   
16 2019-11-25 04:00:00          8.8        10.0             23.0         0.0   

   traffic_state  average_flow  
0          Fluid         218.1  
1          Fluid         218.1  
2          Fluid         218.1  
3          Fluid         218.1  
4          Fluid         144.3  
5          Fluid         144.3  
6          Fluid         144.3  
7          Fluid         144.3  
8          Fluid         110.0  
9          Fluid         110.0  
10         Fluid         110.0  
11         Fluid         110.0  
12         Fluid         143.8  
13         Fluid         143.8  
14         Fluid         143.8  
15         Fluid         143.8  
16         Fluid         315.1 

请注意,最后一行没有增加 15 分钟。如果你想这样做,你需要使用重复。

选项 3:使用 df.resample('15min') 排除带有字符串的列

我们也可以尝试做'resample but it will not retain the string datatypes (traffic_state`不会被复制)。

如果你想使用df.resample,你可以给:

df2 = df.resample('15min',on='timestamp').mean().reset_index().ffill()
print (df2)

这将导致:

             timestamp  temperature  wind_speed  wind_gust_speed  rain_level  \
0  2019-11-25 00:00:00          8.7        11.0             24.0         0.0   
1  2019-11-25 00:15:00          8.7        11.0             24.0         0.0   
2  2019-11-25 00:30:00          8.7        11.0             24.0         0.0   
3  2019-11-25 00:45:00          8.7        11.0             24.0         0.0   
4  2019-11-25 01:00:00          8.8         9.0             20.0         0.0   
5  2019-11-25 01:15:00          8.8         9.0             20.0         0.0   
6  2019-11-25 01:30:00          8.8         9.0             20.0         0.0   
7  2019-11-25 01:45:00          8.8         9.0             20.0         0.0   
8  2019-11-25 02:00:00          8.9         8.0             18.0         0.0   
9  2019-11-25 02:15:00          8.9         8.0             18.0         0.0   
10 2019-11-25 02:30:00          8.9         8.0             18.0         0.0   
11 2019-11-25 02:45:00          8.9         8.0             18.0         0.0   
12 2019-11-25 03:00:00          8.8         7.0             18.0         0.0   
13 2019-11-25 03:15:00          8.8         7.0             18.0         0.0   
14 2019-11-25 03:30:00          8.8         7.0             18.0         0.0   
15 2019-11-25 03:45:00          8.8         7.0             18.0         0.0   
16 2019-11-25 04:00:00          8.8        10.0             23.0         0.0   

    average_flow  
0          218.1  
1          218.1  
2          218.1  
3          218.1  
4          144.3  
5          144.3  
6          144.3  
7          144.3  
8          110.0  
9          110.0  
10         110.0  
11         110.0  
12         143.8  
13         143.8  
14         143.8  
15         143.8  
16         315.1 

同样,这也不会将最后一行增加 15 分钟。

选项 4:使用 df.resample('15min') 包括带有字符串的列(使用 lambda)

df3 = df.resample('15min',on='timestamp').agg({'temperature':'mean','wind_speed':'mean',
                                               'wind_gust_speed':'mean','rain_level':'mean',
                                               'traffic_state':lambda x: x if len(x)>0 else np.nan,
                                               'average_flow':'mean'}).reset_index().ffill()
print (df3)

输出将是:

             timestamp  temperature  wind_speed  wind_gust_speed  rain_level  \
0  2019-11-25 00:00:00          8.7        11.0             24.0         0.0   
1  2019-11-25 00:15:00          8.7        11.0             24.0         0.0   
2  2019-11-25 00:30:00          8.7        11.0             24.0         0.0   
3  2019-11-25 00:45:00          8.7        11.0             24.0         0.0   
4  2019-11-25 01:00:00          8.8         9.0             20.0         0.0   
5  2019-11-25 01:15:00          8.8         9.0             20.0         0.0   
6  2019-11-25 01:30:00          8.8         9.0             20.0         0.0   
7  2019-11-25 01:45:00          8.8         9.0             20.0         0.0   
8  2019-11-25 02:00:00          8.9         8.0             18.0         0.0   
9  2019-11-25 02:15:00          8.9         8.0             18.0         0.0   
10 2019-11-25 02:30:00          8.9         8.0             18.0         0.0   
11 2019-11-25 02:45:00          8.9         8.0             18.0         0.0   
12 2019-11-25 03:00:00          8.8         7.0             18.0         0.0   
13 2019-11-25 03:15:00          8.8         7.0             18.0         0.0   
14 2019-11-25 03:30:00          8.8         7.0             18.0         0.0   
15 2019-11-25 03:45:00          8.8         7.0             18.0         0.0   
16 2019-11-25 04:00:00          8.8        10.0             23.0         0.0   

   traffic_state  average_flow  
0          Fluid         218.1  
1          Fluid         218.1  
2          Fluid         218.1  
3          Fluid         218.1  
4          Fluid         144.3  
5          Fluid         144.3  
6          Fluid         144.3  
7          Fluid         144.3  
8          Fluid         110.0  
9          Fluid         110.0  
10         Fluid         110.0  
11         Fluid         110.0  
12         Fluid         143.8  
13         Fluid         143.8  
14         Fluid         143.8  
15         Fluid         143.8  
16         Fluid         315.1  

同样的问题。我们不会以 15 分钟为增量来处理最后一行。

【讨论】:

    猜你喜欢
    • 2018-11-10
    • 2017-08-19
    • 1970-01-01
    • 1970-01-01
    • 2020-06-16
    • 1970-01-01
    • 2018-08-10
    • 1970-01-01
    相关资源
    最近更新 更多