进行计算以引用同一列中的先前值

时间:2018-07-30 17:16:19

标签: python python-3.x pandas numpy dataframe

我有一个要从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列再次更改?

1 个答案:

答案 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]])