计算自动柜员机中的多余现金量

时间:2019-07-04 13:44:49

标签: python pandas time-series

我想从给定的交易和补给数据集中计算出ATM中剩余的多余金额。

我可以通过遍历数据以从当前金额中减去交易来做到这一点。但是我需要不使用循环来执行此操作。

# R: Replenishment amount
# T: Transaction Amount
'''
R    T 
100  50
0    30
0    10
200  110
0    30 
60   20
'''
data = {'Date':pd.date_range('2011-05-03','2011-05-8' ).tolist(),'R':[100,0,0,200,0,60],'T':[50,30,10,110,30,20]}
df = pd.DataFrame(data)

# calculated temporary amount and shift it to subtract future 
# transactions from it
df['temp'] = ((df['R']-df['T']).shift(1).bfill())

# Boolean indicating whether ATM was replenished or not
# 1: Replenished, 0: Not Replenished
df['replenished'] = (df['R'] >0).astype(int)

# If replenished subtract transaction amount from the replenishment amount
# otherwise subtract it from temp amount
df['replenished']*df['R']+(np.logical_not(df['replenished']).astype(int))*df['temp']-df['T']



Expected Results:
0    50.0
1    20.0
2    10.0
3    90.0
4    60.0
5    40.0
dtype: float64

Actual Results:
0    50.0
1    20.0
2    -40.0
3    90.0
4    60.0
5    40.0
dtype: float64

1 个答案:

答案 0 :(得分:0)

首先,我们计算一个布尔列,以了解是否已对它进行了补充。

df['replenished'] = df['R'] > 0

我们还计算了货币增量,这对执行其余操作很有用。

df['increment'] = df['R'] - df['T']

我们还创建了将在适当的时候具有所需值的列,我将其称为 reserve 。首先,我们计算增量的总和,这是从第一个补货日到下一个补货日的期望值。

df['reserve'] = df['increment'].cumsum()

现在,我们将创建数据帧的辅助别名,这将有助于进行操作而不会丢失原始数据。请记住,此变量不是副本,它指向与原始变量相同的数据:df_aux中的更改将更改原始变量df

df_aux = df

然后,我们可以进行处理问题的循环。

while not df_aux.empty:
    df_aux = df_aux.loc[df_aux.loc[df_aux['replenished']].index[0]:]
    k = df_aux.at[df_aux.index[0], 'reserve']
    l = df_aux.at[df_aux.index[0], 'increment']
    df_aux['reserve'] = df_aux['reserve'] - k + l
    if len(df_aux) > 1:
        df_aux = df_aux.loc[df_aux.index[1]:]
    else:
        break

首先,我们从下一个补货日开始获取所有数据框。从这一天到下一个补货天,如果初始值等于增量,那么累积的总和将为我们提供理想的结果,因此我们修改了累积总和,以使第一个值符合此条件。

然后,如果这是数据帧的最后一行,那么我们的工作就完成了,我们退出了循环。如果不是,那么我们删除刚才计算的补货日,然后继续进行下一天。

所有这些操作之后,结果(df)是这样的:


    Date        R       T       increment   replenished     reserve
0   2011-05-03  100     50      50          True            50
1   2011-05-04  0       30      -30         False           20
2   2011-05-05  0       10      -10         False           10
3   2011-05-06  200     110     90          True            90
4   2011-05-07  0       30      -30         False           60
5   2011-05-08  60      20      40          True            40

我对微积分时间没有经验,所以我不确定这种解决方案是否比遍历所有行更快。