在重采样操作后初始化第一行和最后一行的值?

Initializing values for the first and last row following a resample operation?

例如,给定一个带有 1h Period 的数据帧,我想在新的 5h Period 开始和结束时分别在新列中设置 0 和 1 值。

让我们以这个输入数据为例:

import pandas as pd
from random import seed, randint
from collections import OrderedDict

p1h = pd.period_range(start='2020-02-01 00:00', end='2020-03-04 00:00', freq='1h', name='p1h')

seed(1)
values = [randint(0,10) for p in p1h]
df = pd.DataFrame({'Values' : values}, index=p1h)

结果

df.head(10)

                  Values
p1h                     
2020-02-01 00:00       2
2020-02-01 01:00       9
2020-02-01 02:00       1
2020-02-01 03:00       4
2020-02-01 04:00       1
2020-02-01 05:00       7
2020-02-01 06:00       7
2020-02-01 07:00       7
2020-02-01 08:00      10
2020-02-01 09:00       6

有什么方法可以设置一个新的列来得到下面的结果吗? (每个周期的第一行和最后一行分别用 0 和 1 初始化)

df['period5h'] = df.resample('5h').???

df.head(10)

                  Values   period5h
p1h                     
2020-02-01 00:00       2          0   <- 1st row of 5h period
2020-02-01 01:00       9
2020-02-01 02:00       1
2020-02-01 03:00       4
2020-02-01 04:00       1          1   <- last row of 5h period
2020-02-01 05:00       7          0   <- 1st row of 5h period
2020-02-01 06:00       7
2020-02-01 07:00       7
2020-02-01 08:00      10
2020-02-01 09:00       6          1   <- last row of 5h period

拜托,这可以用 pandas 中的某些功能以某种方式完成吗?

然后,最终目标是通过 0 和 1 之间的线性插值来填充空值,以便获得相对于 5 小时周期的当前行的百分比进度。

另一个曲目/问题

另一种方法可能是使用 5h PeriodIndex 初始化第二个 DataFrame,将新列的值初始化为 1,然后将 PeriodIndex 上采样回 1H 合并两个 DataFrame。

shift(-1) 将初始化句点的最后一行。

我会重复这个过程,而不移动值 0。

那么,我该如何创建这个新的 DataFrame 以便我可以将它合并到 1st?我尝试了一些合并命令,但出现错误,提示我两个索引的频率不同。

感谢您的帮助!最佳

不是大多数 pythonic 方法,但它有效。

import pandas as pd
from random import seed, randint
from collections import OrderedDict
import time
p1h = pd.period_range(start='2020-02-01 00:00', end='2040-03-04 00:00', freq='1h', name='p1h')

seed(1)
values = [randint(0,10) for p in p1h]
df = pd.DataFrame({'Values' : values}, index=p1h)

t1 = time.time()
for i in range(len(df['Values'])):
  if (i+1)% 5 == 1:
    df['Values'].iloc[i] = 0
  elif (i+1) % 5 == 0:
    df['Values'].iloc[i] = 1
t2 = time.time()
df.head(20)

print(t2-t1)


时间:8.770591259002686

方法二:

import pandas as pd
from random import seed, randint
from collections import OrderedDict
import time
p1h = pd.period_range(start='2020-02-01 00:00', end='2040-03-04 00:00', freq='1h', name='p1h')

seed(1)
values = [randint(0,10) for p in p1h]
df = pd.DataFrame({'Values' : values}, index=p1h)

t1 = time.time()

df['Values'].iloc[range(0,len(df['Values']),5)] = 0
df['Values'].iloc[range(4,len(df['Values']),5)] = 1
t2 = time.time()
df.head(20)

print(t2-t1)

时间:0.009400367736816406

使用重采样对象的 indices 属性来查找组的第一个和最后一个索引。即使数据没有规则频率,或者其频率不能完全除以重采样频率,这也会起作用。组将只有一个测量值设置为 1 而不是 0。然后我们相应地设置值

i1 = [] # Last `.iloc` index labels
i0 = [] # First `.iloc` index labels
for k,v in df.resample('5H').indices.items():
    i0.append(v[0])
    i1.append(v[-1])

df.loc[df.index[i0], 'period_5H'] = 0
df.loc[df.index[i1], 'period_5H'] = 1

                  Values  period_5H
p1h                                
2020-02-01 00:00       2        0.0
2020-02-01 01:00       9        NaN
2020-02-01 02:00       1        NaN
2020-02-01 03:00       4        NaN
2020-02-01 04:00       1        1.0
2020-02-01 05:00       7        0.0
2020-02-01 06:00       7        NaN
2020-02-01 07:00       7        NaN
2020-02-01 08:00      10        NaN
2020-02-01 09:00       6        1.0
2020-02-01 10:00       3        0.0
...

好的,我最终设置为使用以下相当快的方法(无循环)

 super_pi = pd.period_range(start='2020-01-01 00:00', end='2020-06-01 00:00', freq='5h', name='p5h')
 super_df = pd.DataFrame({'End' : 1, 'Start' : 0}, index=super_pi).resample('1h').first()
 # We know last row is a 1 (end of period)
 super_df['End'] = super_df['End'].shift(-1, fill_value=1)
 super_df['Period'] = super_df[['End','Start']].sum(axis=1, min_count=1)

结果

 supder_df.head(10)

                   End  Start  Period
 p5h                                 
 2020-01-01 00:00  NaN    0.0     0.0
 2020-01-01 01:00  NaN    NaN     NaN
 2020-01-01 02:00  NaN    NaN     NaN
 2020-01-01 03:00  NaN    NaN     NaN
 2020-01-01 04:00  1.0    NaN     1.0
 2020-01-01 05:00  NaN    0.0     0.0
 2020-01-01 06:00  NaN    NaN     NaN
 2020-01-01 07:00  NaN    NaN     NaN
 2020-01-01 08:00  NaN    NaN     NaN

最佳,