我在python中具有以下数据框:
month = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,1,2,3,4]
active = [1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1]
data1 = [1709.1,3869.7,4230.4,4656.9,48566.0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,93738.2,189293.2,194412.6,206585.8]
df = pd.DataFrame({
'month' : month,
'active' : active,
'd1' : data1,
'calculate' : 0,
});
并且我想通过以下方式计算“计算”列:
month active d1 calculate 0 1 1 1709.1 569.70 1 2 1 3869.7 1859.60 2 3 1 4230.4 3269.73 3 4 1 4656.9 4822.03 4 5 0 48566.0 0.00 5 6 0 0.0 0.00 6 7 0 0.0 0.00 7 8 0 0.0 0.00 8 9 0 0.0 0.00 9 10 0 0.0 0.00 10 11 0 0.0 0.00 11 12 0 0.0 0.00 12 13 0 0.0 0.00 13 14 0 0.0 0.00 14 15 0 0.0 0.00 15 16 0 0.0 0.00 16 17 0 0.0 0.00 17 18 0 0.0 0.00 18 19 0 0.0 0.00 19 20 0 0.0 0.00 20 1 1 93738.2 31246.07 21 2 1 189293.2 94343.80 22 3 1 194412.6 159148.00 23 4 1 206585.8 228009.93
我通过以下方式进行操作:
df['calculate'] = np.where(
df.month > 1,
np.where(
df.active,
(df.d1/3).cumsum(),
0,
),
(df['d1']/3)
)
但结果不是预期的:
month active d1 calculate 0 1 1 1709.1 569.700000 1 2 1 3869.7 1859.600000 2 3 1 4230.4 3269.733333 3 4 1 4656.9 4822.033333 4 5 0 48566.0 0.000000 5 6 0 0.0 0.000000 6 7 0 0.0 0.000000 7 8 0 0.0 0.000000 8 9 0 0.0 0.000000 9 10 0 0.0 0.000000 10 11 0 0.0 0.000000 11 12 0 0.0 0.000000 12 13 0 0.0 0.000000 13 14 0 0.0 0.000000 14 15 0 0.0 0.000000 15 16 0 0.0 0.000000 16 17 0 0.0 0.000000 17 18 0 0.0 0.000000 18 19 0 0.0 0.000000 19 20 0 0.0 0.00 20 1 1 93738.2 31246.07 21 2 1 189293.2 115354.50 22 3 1 194412.6 180158.70 23 4 1 206585.8 249020.63
我不知道我的要求是否明确,谢谢谁能帮助我。
答案 0 :(得分:1)
新答案
您使问题变得更加复杂,可以将问题简化为:
df.groupby(df.active.ne(df.active.shift()).cumsum()).d1.cumsum().div(3) * df.active
0 569.700000
1 1859.600000
2 3269.733333
3 4822.033333
4 0.000000
5 0.000000
6 0.000000
7 0.000000
8 0.000000
9 0.000000
10 0.000000
11 0.000000
12 0.000000
13 0.000000
14 0.000000
15 0.000000
16 0.000000
17 0.000000
18 0.000000
19 0.000000
20 31246.066667
21 94343.800000
22 159148.000000
23 228009.933333
dtype: float64
旧答案 (我认为包括来解释所尝试内容的逻辑仍然很有用)
您只想要1s的连续区域的累积总和,但是,当您到达DataFrame的末尾时,您将继续其余DataFrame的累积总和。一种解决方案是计算每组连续1的cumsum
,然后在最终检查中使用此结果。
当np.where
更容易阅读时,我还希望避免将调用链接到np.select
。
s = df.groupby(df.active.ne(df.active.shift()).cumsum()).d1.cumsum()
c1 = df.month.gt(1) & df.active
c2 = df.month.gt(1) & ~df.active
df.assign(calculate=np.select([c1, c2], [s.div(3), 0], df.d1.div(3)))
month active d1 calculate
0 1 1 1709.1 569.700000
1 2 1 3869.7 1859.600000
2 3 1 4230.4 3269.733333
3 4 1 4656.9 4822.033333
4 5 0 48566.0 0.000000
5 6 0 0.0 0.000000
6 7 0 0.0 0.000000
7 8 0 0.0 0.000000
8 9 0 0.0 0.000000
9 10 0 0.0 0.000000
10 11 0 0.0 0.000000
11 12 0 0.0 0.000000
12 13 0 0.0 0.000000
13 14 0 0.0 0.000000
14 15 0 0.0 0.000000
15 16 0 0.0 0.000000
16 17 0 0.0 0.000000
17 18 0 0.0 0.000000
18 19 0 0.0 0.000000
19 20 0 0.0 0.000000
20 1 1 93738.2 31246.066667
21 2 1 189293.2 94343.800000
22 3 1 194412.6 159148.000000
23 4 1 206585.8 228009.933333