Taking first value in a rolling window that is not numeric

为君一笑 提交于 2020-04-30 07:15:26

问题


This question follows one I previously asked here, and that was answered for numeric values.

I raise this 2nd one now relative to data of Period type.

While the example given below appears simple, I have actually windows that are of variable size. Interested in the 1st row of the windows, I am looking for a technic that makes use of this definition.

import pandas as pd
from random import seed, randint

# DataFrame
pi1h = pd.period_range(start='2020-01-01 00:00+00:00', end='2020-01-02 00:00+00:00', freq='1h')

seed(1)
values = [randint(0, 10) for ts in pi1h]

df = pd.DataFrame({'Values' : values, 'Period' : pi1h}, index=pi1h)

# This works (numeric type)
df['first'] = df['Values'].rolling(3).agg(lambda rows: rows[0])

# This doesn't (Period type)
df['OpeningPeriod'] = df['Period'].rolling(3).agg(lambda rows: rows[0])

Result of 2nd command

DataError: No numeric types to aggregate

Please, any idea? Thanks for any help! Bests,


回答1:


First row of rolling window of size 3 means row, which is 2 rows above the current - just use pd.Series.shift(2):

df['OpeningPeriod'] = df['Period'].shift(2)

For the variable size (for the sake of example- I took Values column as this variable size):

import numpy as np

x=(np.arange(len(df))-df['Values'])

df['OpeningPeriod'] = np.where(x.ge(0), df.loc[df.index[x.tolist()], 'Period'], np.nan)



回答2:


Convert your period[H] to a float

# convert to float
df['Period1'] = df['Period'].dt.to_timestamp().values.astype(float)
# rolling and convert back to period
df['OpeningPeriod'] = pd.to_datetime(df['Period1'].rolling(3)\
                                     .agg(lambda rows: rows[0])).dt.to_period('1h')
# drop column
df = df.drop(columns='Period1')


来源:https://stackoverflow.com/questions/60973941/taking-first-value-in-a-rolling-window-that-is-not-numeric

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!