Pandas应用程序(),条件为最后一个notnull值及其索引



我现在正在处理的代码有问题,所以基本上我得到的是一个数据帧,其中有一列用pd形式的数字填充。例如,数据帧([2,2,2,0,0,0,0,2,0,2](。所以我想要的输出是[2,2,2,0,0,0,10,0,4](就像记忆效果(。

所以我在想,如果有一种方法可以做这样的事情:

df.apply(lambda x: x * (index(x) - index( lastnotnull(x) ) ) if x!=0 else 0, axis=1)

任何想法都可以,但最好是优化的。

lastnotnull并不是一个真正的函数,它只是解释我想法的一种方式。所以基本上,我想要的是,在每一行中,它检查它是否为null,如果它是0,否则它将它乘以(以前的null值的数量+1(,所以在我的例子中,第四个2变成2*(7-"2"(=10,7是2的索引,变为10;2〃;是列表中第三个2的索引,它是列表的最后一个非空值。

您在文章中包含了一个如何计算预期值:(2 * (7 - 2) = 10(。这表明一个更精确的公式,对于值!=0,更确切地说是:

x * (index(x) - index(previousNonZero(x)))

注意以下差异:

  • lastnotnull(如您所写(表示当前列,而不管当前元素是什么。如果此列不包含NaN,则这是最后行中的元素
  • previousNonZero(一个更精确的公式(表示您从当前元素向上查找元素就是!=0。您没有指定如何处理第一行,其中没有前一行,所以我假设这种情况将是0(与第一行相同(

为了有一些列名,而不是默认的0,我创建了源DataFrame为:

df = pd.DataFrame({'x': [2, 2, 2, 0, 0, 0, 0, 2, 0, 2]})

从而将该列命名为x

为了容易地找到先前的非零元素(及其索引(,让我们创建一个辅助DataFrame:

wrk = df[df.x != 0]

要生成预期结果,请运行:

result = np.where(df.x != 0, df.x * (wrk.index - wrk.index.to_series()
.shift(fill_value=0)), 0).astype(int)

详细信息:

  • df.x != 0-条件参数到np。其中
  • wrk.index.to_series().shift(fill_value=0)-x列中的前一个非零元素(替换了初始NaN0(
  • df.x * (wrk.index - ...)-x!=的公式0情况下
  • 0-x==0情况下的公式
  • astype(int)-将结果转换为int(否则为float(

结果是:

array([ 0,  2,  2,  0,  0,  0,  0, 10,  0,  4])

请注意,第一个元素与您的预期结果不同,但这是所用公式的结果。

为了支持我的观点,让我们分析第一行的情况:

  • CCD_ 7=2
  • CCD_ 8==0
  • CCD_ 9==0
  • CCD_ 10==0
  • 最终结果==0

一种替代方案:将fill_value更改为-1("假设";前一行(如果存在((,结果将如您所愿。

编辑

上面的代码可以重新编写成一个函数,对任何列进行操作源DataFrame:

def proc(col):
wrk = col[col != 0]
return (col * (wrk.index - wrk.index.to_series()
.shift(fill_value=-1))).fillna(0, downcast='infer')

在该函数中,仍然会创建一个临时系列(wrk(,但是退出该函数后,它将被垃圾收集,所以不用担心关于这个细节。

现在你可以称之为:

result = proc(df.x)

获取(这次是系列(:

0     2
1     2
2     2
3     0
4     0
5     0
6     0
7    10
8     0
9     4
dtype: int64

左列是索引和右值(以前在数组中(。

如果需要,请将此函数的名称更改为您选择的任何其他名称(我没有更好的主意(。

最新更新