我一直在尝试从两个初始布尔数组(df1和df2)创建一个新的布尔数组,遵循以下规则:
- 如果在df1中看到最后一个True值,则df3中的值为True - 如果在df2中看到最后一个True值,则df3中的值为False
我找到了一种方法,通过减去两个数组,然后用NaN值重新计算0值,使用.fillna
方法填充NaN值,最后将-1值重新设置为0. / p>
代码看起来像这样(以随机数组为例):
将pandas导入为pd 将matplotlib.pyplot导入为plt 导入numpy为np
df1 = pd.Series((1,1,1,0,0,0,0,0,0,0,
0,0,0,0,1,0,0,1,0,0,
0,0,0,0,0,1,1,1,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,1,1,1,0,0,0,0))
df2 = pd.Series((0,0,0,0,0,0,1,1,0,0,
0,0,0,0,0,0,0,0,0,0,
1,0,0,0,0,0,0,0,0,0,
0,0,0,1,0,0,1,0,0,0,
0,0,0,0,0,0,0,0,0,0))
df3 = df1-df2
df3 = df3.replace(0,np.nan).fillna(method='ffill')
df3 = df3.replace(-1,0)
它完成了技巧并返回了我想要的数组,但似乎没有优化像这样多次重新设置值,并使用fillna
方法来做我想要的。
有没有人知道如何更“正确”地执行此操作,并且如果有一个类似于fillna
的方法,但是除了NaN之外的其他值?
优化对于这个问题非常重要,因为我会花很多时间来完成这个过程。
答案 0 :(得分:1)
这应该更快一些(200,000行大约6倍,但当然要检查一下)。 import numpy as np
之后:
arr = np.select( [df1==1,df2==1], [1,0], default=np.nan )
ser = pd.Series( arr ).ffill()
如果您不熟悉np.select
,它与np.where
非常相似,但允许多种条件。你也可以做一个嵌套的np.where
,但这更具可读性。
以下是arr,允许您执行简单的ffill
而无需使用replace
两次的原因是,您有nan
而不是零。
array([ 1., 1., 1., nan, nan, nan, 0., 0., nan, nan, nan,
nan, nan, nan, 1., nan, nan, 1., nan, nan, 0., nan,
nan, nan, nan, 1., 1., 1., nan, nan, nan, nan, nan,
0., nan, nan, 0., nan, nan, nan, nan, nan, nan, 1.,
1., 1., nan, nan, nan, nan])
你可以通过存储df1和amp;来获得更快的速度。 df2作为numpy数组而不是数据帧/系列,但我认为它不会太重要。
如果速度确实是一个问题,你应该尝试在numpy而不是pandas(如果可能的话)中做所有事情,但我不确定pandas ffill
是否有一个好的numpy模拟。