仅当有限且非零时将值从一个系列/数据帧复制到另一个,并在非有限且为零时保留现有值
Copy value from one Series / DataFrame to Another only when is finite and nonzero and preserve existing value when not finite and zero
我有一个包含值和零的系列,它保存给定时间点的当前读数 (newv
)。零表示给定的一组读数没有新读数。我想用最后一个已知值 (vals
) 维护另一个系列。
为此,您应该能够将包含当前值的系列中的非零值复制到具有最后已知值的系列中,并且当当前值的读数为零时,还可以保留最后已知值中的值(结果 vals
)。
如何将这些数据结构维护为系列和数据框?
例如
给定 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])
好的,通过更新的示例,我认为您只需要在 newv
大于零的任何地方为 vals
分配新值。这样做:
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
s 替换 Series 中的零值然后使用 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')
我有一个包含值和零的系列,它保存给定时间点的当前读数 (newv
)。零表示给定的一组读数没有新读数。我想用最后一个已知值 (vals
) 维护另一个系列。
为此,您应该能够将包含当前值的系列中的非零值复制到具有最后已知值的系列中,并且当当前值的读数为零时,还可以保留最后已知值中的值(结果 vals
)。
如何将这些数据结构维护为系列和数据框?
例如
给定 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])
好的,通过更新的示例,我认为您只需要在 newv
大于零的任何地方为 vals
分配新值。这样做:
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
s 替换 Series 中的零值然后使用 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')