我有一个要从Excel电子表格复制的数据框。它具有值列表,并且在最后一列中,如果RunningTotal = Max,则公式应为:则值应为0。如果Max等于max.shift(1),则值应为Diff的最小值列,以及MaxDraw列的上一个值。
list = [-350, 1350, 300, 300, -500, -100, -550, 1450,
-3900, -1150, 4150, -1900, 1700, 7750, -3050, -1450, -1850, 4250]
df = pd.DataFrame(data=list, columns=['Values'])
df['RunningTotal'] = df['Values'].cumsum()
df['Max'] = df['RunningTotal'].cummax()
df['Diff'] = df['RunningTotal']-df['Max']
df['MaxDraw'] = np.where(df['RunningTotal'] == df['Max'], 0,
np.where(df['Max'] == df['Max'].shift(1),
**np.minimum(df['MaxDraw'].shift(1)**, df['Max']), np.nan))
我曾尝试过使用双星号代码段,但似乎无法在我定义的行中引用值。我尝试做一个临时列,但我需要先前的值才能获得最终结果。
预期结果应与下面的MaxDraw列匹配。
Vales Running Total Max MaxDraw
-350 -350 NA NA
1350 1000 1000 0
300 1300 1300 0
300 1600 1600 0
-500 1100 1600 -500
-100 1000 1600 -600
-550 450 1600 -1150
1450 1900 1900 0
-3900 -2000 1900 -3900
-1150 -3150 1900 -5050
4150 1000 1900 -5050
-1900 -900 1900 -5050
1700 800 1900 -5050
7750 8550 8550 0
-3050 5500 8550 -3050
-1450 4050 8550 -4500
-1850 2200 8550 -6350
4250 6450 8550 -6350
D3中的excel论坛是 = IF(A3 =“”,“”,IF(C3 = B3,0,IF(C3 = C2,MIN(B3-C3,D2))))
任何帮助都将不胜感激,因为我已经将头撞在墙上超过一段时间了!
编辑:
在尝试保持此向量化而不必使用迭代的情况下-是否有一种解决方案将使用np.where,并且说如果max列不等于max列的前一行,则该值等于0-否则返回diff列的运行最小值,直到max列再次更改?
答案 0 :(得分:1)
您将需要在此处使用显式的for循环:
m = []
for i in df.index:
if df.iloc[i,1]==df.iloc[i,2]:
m.append(df.iloc[i,3])
else:
m.append(min(m[i-1],df.iloc[i,3]))
df["MAXDRAW"]=m
df
Values RunningTotal Max Diff MAXDRAW
0 -350 -350 -350 0 0
1 1350 1000 1000 0 0
2 300 1300 1300 0 0
3 300 1600 1600 0 0
4 -500 1100 1600 -500 -500
5 -100 1000 1600 -600 -600
6 -550 450 1600 -1150 -1150
7 1450 1900 1900 0 0
8 -3900 -2000 1900 -3900 -3900
9 -1150 -3150 1900 -5050 -5050
10 4150 1000 1900 -900 -5050
11 -1900 -900 1900 -2800 -5050
12 1700 800 1900 -1100 -5050
13 7750 8550 8550 0 0
14 -3050 5500 8550 -3050 -3050
15 -1450 4050 8550 -4500 -4500
16 -1850 2200 8550 -6350 -6350
17 4250 6450 8550 -2100 -6350
如果您需要此功能,则可以使用itertools.accumulate
。
list(itertools.accumulate([df.iloc[0,3]]+df.iloc[1:].values.tolist(),lambda x,y:y[3] if y[1]==y[2] else min(x,y[3])))
这也与functools.reduce
functools.reduce(lambda x,y:x+[y[3]]if y[1]==y[2] else x+[min(x[-1],y[3])],df.iloc[1:].values.tolist(),[df.iloc[0,3]])