仅在有限且非零时将值从一个Series / DataFrame复制到另一个,并在非有限和零时保留现有值

时间:2017-04-16 10:09:17

标签: python pandas dataframe series

我有一个具有值和零的系列,它在给定的时间点保存当前读数(newv)。零表示给定的读数组没有新的读数。我想维护另一个具有上一个已知值(vals)的系列。

为此,您应该能够将保存当前值的系列中的非零值复制到具有最后已知值的系列,并在当前值的读数为零时保留最后已知值中的值(结果vals)。

如何将这些数据结构维护为系列和数据框?

E.g。

鉴于vals = pd.Series([1, 2, 3, 4, 5, 6, 7, 8, 9])newv = pd.Series([0, 22, 0, 44, 0, 0, 0, 0, 0]),我希望到达vals = pd.Series([1, 22, 3, 44, 5, 6, 7, 8, 9])

在下一次迭代中给出vals = pd.Series([1, 22, 3, 44, 5, 6, 7, 8, 9])newv = pd.Series([11, 0, 33, 0, 0, 0, 0, 0, 0]),我想到达vals = pd.Series([11, 22, 33, 44, 5, 6, 7, 8, 9])

1 个答案:

答案 0 :(得分:2)

好的,通过更新的示例,我认为您需要为vals分配新值,而newv大于零。这样做:

vals = pd.Series([1, 2, 3, 4, 5, 6, 7, 8, 9])
newv = pd.Series([0, 22, 0, 44, 0, 0, 0, 0, 0])
vals.loc[newv>0] = newv

如果您有一个带有一些新迭代列的DataFrame,您可以创建一个包含上述已知值的列,如下所示:

df = pd.DataFrame()
df['vals'] = [1, 2, 3, 4, 5, 6, 7, 8, 9]
df['new1'] = [0, 22, 0, 44, 0, 0, 0, 0, 0]
df['new2'] = [11, 0, 33, 0, 0, 0, 0, 0, 0]
df['last_known'] = df.apply(lambda x: x[x>0].iloc[-1], axis=1)

或者您可以在df列上应用上一个答案的方法,并在每次迭代时获取当前值:

df.apply(pd.Series.replace, axis=1, to_replace=0, method='ffill')

哪个会产生

   vals  new1  new2
0     1     1    11
1     2    22    22
2     3     3    33
3     4    44    44
4     5     5     5
5     6     6     6
6     7     7     7
7     8     8     8
8     9     9     9

原来的答案

您可以使用NaN替换系列中的零值,然后使用fillna方法转发填充缺失值来执行此操作。例如:

import pandas as pd
import numpy as np

s1 = pd.Series([1,2,3,0,0,0,4,0,5])
s2 = s1.replace({0:np.NaN}).fillna(method='ffill')

这是s2

中的结果
0    1.0
1    2.0
2    3.0
3    3.0
4    3.0
5    3.0
6    4.0
7    4.0
8    5.0

正如@ayhan在评论中建议的更好的方法是将replace与方法参数一起使用:

s2 = s1.replace(0, method='ffill')