Python 数据帧根据条件按上一行值更新行值

Python 数据帧根据条件按上一行值更新行值,python,pandas,Python,Pandas,我有一个如下的数据帧。我想根据以下条件替换行值 如果3个连续的前一行值为0,则保持该值不变,或者如果只有一个前一行值为0,则通过该特定IEMI最后3行的滚动平均值填充该行 首先是数据帧(df) 请遵守预期KVA列的计算。由于第9行的实际KVA值为0,Expected KVA的值是IEMI 55647最近三次观测(KVA)的简单平均值。但在第3、第4和第5行,由于IEMI 55647的3KVA值为0,因此预期KVA值也为0 编辑 编辑-进一步 下面是一段伪代码片段。我有reset\u索引。但它可能

我有一个如下的数据帧。我想根据以下条件替换行值

如果3个连续的前一行值为0,则保持该值不变,或者如果只有一个前一行值为0,则通过该特定IEMI最后3行的滚动平均值填充该行

首先是
数据帧(df)

请遵守
预期KVA
列的计算。由于第9行的实际
KVA
值为0,
Expected KVA
的值是IEMI 55647最近三次观测(
KVA
)的简单平均值。但在第3、第4和第5行,由于IEMI 55647的3
KVA
值为0,因此
预期KVA
值也为0

编辑 编辑-进一步 下面是一段伪代码片段。我有
reset\u索引
。但它可能不起作用

df = df.sort_values(['IMEI'],ascending=0).reset_index(drop=True)
for i in range(0,len(df)):
     if df.loc[i:i+2,'KVA']==0:
          df['Expected KVA'] = df['KVA']
     else:
        df['Expected KVA']=df.groupby('IEMI')['KVA'].rolling(min_periods=1,center=True,window=3).mean()
我相信上面的代码片段可能会失败,因为我对IEMI进行了排序,因此索引被扭曲了


如何实现这一目标?与
groupby
功能耦合的
循环?有什么想法吗

下面是我的想法:(我用IMEI:55674额外添加了3行,只是为了测试)

用一组3(无需操作)删除连续0并在数据帧上切片:

import itertools
def consecutive(data, stepsize=1):
    return np.split(data, np.where(np.diff(data) != stepsize)[0]+1)

a = np.array(df[df.KVA == 0.00].index)
l = consecutive(a)
to_exclude=list(itertools.chain.from_iterable([i.tolist() for i in l if len(i)==3]))
pd.options.mode.chained_assignment = None
df1 = df.loc[~df.index.isin(to_exclude)]
>>df1
    IMEI    KVA     KwH
0   55647   1307.65 1020.33
1   55468   2988.00 1109.05
5   55469   1888.97 933.48
6   55647   1338.65 1120.33
7   55468   2088.00 1019.05
8   55647   0.00    977.87
9   55469   1455.28 1388.25
10  55648   2144.38 445.37
11  55469   1888.97 933.48
12  55674   0.00    6433.00
13  55674   1345.00 6542.00
14  55674   3456.00 6541.00
pd.concat([df1,df.loc[df.index.isin(to_exclude)]]).sort_index()

    IMEI    KVA         KwH
0   55647   1307.650000 1020.33
1   55468   2988.000000 1109.05
2   55647   0.000000    977.87
3   55467   0.000000    1388.25
4   55647   0.000000    445.37
5   55469   1888.970000 933.48
6   55647   1338.650000 1120.33
7   55468   2088.000000 1019.05
8   55647   882.100000  977.87
9   55469   1455.280000 1388.25
10  55648   2144.380000 445.37
11  55469   1888.970000 933.48
12  55674   1600.333333 6433.00
13  55674   1345.000000 6542.00
14  55674   3456.000000 6541.00
np.nan
分配剩余的0,用
transform
执行
groupby
,并用均值
fillna

df1['KVA'] = df1['KVA'].replace(0, np.nan)
df1['KVA'] = df1['KVA'].fillna(df1.fillna(0).groupby(['IMEI'])['KVA'].transform('mean'))
>>df1
    IMEI    KVA          KwH
0   55647   1307.650000 1020.33
1   55468   2988.000000 1109.05
5   55469   1888.970000 933.48
6   55647   1338.650000 1120.33
7   55468   2088.000000 1019.05
8   55647   882.100000  977.87
9   55469   1455.280000 1388.25
10  55648   2144.380000 445.37
11  55469   1888.970000 933.48
12  55674   1600.333333 6433.00
13  55674   1345.000000 6542.00
14  55674   3456.000000 6541.00
然后只需
concat
sort\u index
我们之前遗漏的内容:

import itertools
def consecutive(data, stepsize=1):
    return np.split(data, np.where(np.diff(data) != stepsize)[0]+1)

a = np.array(df[df.KVA == 0.00].index)
l = consecutive(a)
to_exclude=list(itertools.chain.from_iterable([i.tolist() for i in l if len(i)==3]))
pd.options.mode.chained_assignment = None
df1 = df.loc[~df.index.isin(to_exclude)]
>>df1
    IMEI    KVA     KwH
0   55647   1307.65 1020.33
1   55468   2988.00 1109.05
5   55469   1888.97 933.48
6   55647   1338.65 1120.33
7   55468   2088.00 1019.05
8   55647   0.00    977.87
9   55469   1455.28 1388.25
10  55648   2144.38 445.37
11  55469   1888.97 933.48
12  55674   0.00    6433.00
13  55674   1345.00 6542.00
14  55674   3456.00 6541.00
pd.concat([df1,df.loc[df.index.isin(to_exclude)]]).sort_index()

    IMEI    KVA         KwH
0   55647   1307.650000 1020.33
1   55468   2988.000000 1109.05
2   55647   0.000000    977.87
3   55467   0.000000    1388.25
4   55647   0.000000    445.37
5   55469   1888.970000 933.48
6   55647   1338.650000 1120.33
7   55468   2088.000000 1019.05
8   55647   882.100000  977.87
9   55469   1455.280000 1388.25
10  55648   2144.380000 445.37
11  55469   1888.970000 933.48
12  55674   1600.333333 6433.00
13  55674   1345.000000 6542.00
14  55674   3456.000000 6541.00

@安德烈亚斯:我会更新相同的……不过,我们的想法是让社区成员得到答案。或者至少是每个人所说的方法。仅仅提到一些琐碎的问题或“降级”并没有帮助。@pythondumb:为什么您希望索引为0.0055469@anky_91:我错了,应该是1455.28。@pythondumb所以你的问题是得到滚动平均值还是否定3个一组的0.00?是的!!我会说“等同”而不是“否定”,谢谢。这似乎解决了我的问题。我可以使用
rolling(window=3)代替
transform('mean')
?@pythondumb。我还没有测试过,但是如果它返回相同的数据,你可以。:)