熊猫:如何纠正小于前一个的值和一些模式



>我有以下时间序列:

2017-11-01 200.000000 2017-12-01 394.000000 2018-01-01 537.000000 2018-02-01 537.000000 2018-03-01 537.000000 2018-04-01 537.000000 2018-05-01 537.000000 2018-06-01 537.000000 2018-07-01 137.000000 2018-08-01 88.000000 2018-09-01 10.000000 2018-10-01 100.000000 2018-11-01 100.000000 2018-12-01 111.000000 2019-01-01 362.000000 2019-02-01 563.000000 2019-03-01 706.000000 2019-04-01 750.000000 2019-05-01 785.000000 2019-06-01 785.000000

我正在处理一个周期性的时间序列,其中的值是从 9 月到 8 月累积的。 在 9 月份,该值应低于前一个值。前几个月并非如此! 所以,我的时间序列是错误的 2018-07-01 和 2018-08-01,但在 2018-09-01 是正确的。 我想用 2018-06-01 (537.0( 中的最后一个值替换这些值。

我使用了 .shift(1( 熊猫选项,但我只能用 6 月的值替换 7 月的值,但我用之前的 7 月值替换了 8 月!这是我使用的代码:

new_df = pd.DataFrame({'date': new_df.index.tolist(), 'vals': new_df.tolist()}) # from df to ts
new_df['shift_values'] = new_df['vals'].shift(1) # create a col with previous values
new_df['diff'] = new_df.apply(lambda x: x['vals']-x['shift_values'], axis=1) # calculate the difference
new_df['valore_finale'] = new_df.apply(lambda x: x['vals'] if x['date'] == '2019-09-01' else(x['vals'] if x['diff']>0 else x['shift_values']), axis=1)

2017-11-01 200.000000 2017-12-01 394.000000 2018-01-01 537.000000 2018-02-01 537.000000 2018-03-01 537.000000 2018-04-01 537.000000 2018-05-01 537.000000 2018-06-01 537.000000 2018-07-01 537.000000 # changed 2018-08-01 537.000000 # changed 2018-09-01 10.000000 # no changed 2018-10-01 100.000000 2018-11-01 100.000000 2018-12-01 111.000000 2019-01-01 362.000000 2019-02-01 563.000000 2019-03-01 706.000000 2019-04-01 750.000000 2019-05-01 785.000000 2019-06-01 785.000000

我找到了一个非常贪婪但有效的解决方案!

results = [new_df.vals[0]]
new_value = 0
for index, values in new_df[1:].iterrows():
if '09' not in str(values.date):  # if date is not September
if values.vals < new_value:
new_value = new_value
else:
new_value = values.vals
else:
new_value = values.vals
results.append(new_value)
new_df['new_values'] = [r for r in results]

希望有人能够用熊猫找到更好的东西。

首先转换为日期时间,以便能够根据要修改的月份使用mask

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

然后使用Series.mask作为NaN要更改的值,然后填充 Series.ffill

df['vals']=df['vals'].mask((df['date'].dt.month<9) & (df['vals']<df['vals'].shift())).ffill()
print(df)
date   vals
0  2017-11-01  200.0
1  2017-12-01  394.0
2  2018-01-01  537.0
3  2018-02-01  537.0
4  2018-03-01  537.0
5  2018-04-01  537.0
6  2018-05-01  537.0
7  2018-06-01  537.0
8  2018-07-01  537.0
9  2018-08-01  537.0
10 2018-09-01   10.0
11 2018-10-01  100.0
12 2018-11-01  100.0
13 2018-12-01  111.0
14 2019-01-01  362.0
15 2019-02-01  563.0
16 2019-03-01  706.0
17 2019-04-01  750.0
18 2019-05-01  785.0
19 2019-06-01  785.0

如果 1 月份必须不考虑上一年 12 月的值,则必须使用 Groupby。

g=df.groupby(df['date'].dt.year)['vals']
df['vals']=df['vals'].mask( (df['vals']<g.shift())&(df['date'].dt.month<9) ).ffill()

Series.shift用于与前一个进行比较。

datetime.dt.month 用于获取九月之前的月份

最新更新