Python 中给定数字的最小行数

The minimum number of rows that sum to a given number in Python

我有一个包含现金、流入和流出的 DataFrame。 我需要创建一个特征 survival,即现金足以支付流出预测的最大周期数(不包括计算中的流入)。

下面以table为例。

同样,流入不计入此练习)。
t=1 中,从初始现金 = 100,我可以添加流出:-20、-50、-10、-10 e 仍然有正现金 (100-20-50-10-10 = 10 > 0) 而随着 t=5 的流出,现金将为负数。所以,只要我能在 survival = 4.
的 t=1 中“存活”4 个时期 在t=2survival = 3等等。

因为它是一个很大的 DataFrame,我如何使用 Pandas 高效地完成它?

t cash outflow inflow survival
1 100 -20 10 4
2 90 -50 10 3
3 50 -10 80 2
4 120 -10 70 ...
5 40 -50 60 ...

我会这样做:

df['survival'] = [ (cash + df.iloc[i:].outflow.cumsum()>0).sum() for i,cash in enumerate(df.cash)]

输出:

   t  cash  outflow  survival
0  1   100      -20         4
1  2    90      -50         3
2  3    50      -10         2
3  4   120      -10         2
4  5    40      -50         0

解释: 我在 cash 值上循环,同时使用 enumerate 跟踪行号。我使用行号 select 仅从当前值 cash 下降的数据帧部分。在数据框的这一部分,我进行了累加,然后将其添加到现金中。当现金小于先前流出的总和时,这会产生一个负数序列。然后我将它设置为 >0,所以当它为正时我有 True 值,当它为负时我有 False 值。我最后对整个系列求和,每个 True 算作一个 1,所以输出就是你要找的生存数。希望它有意义。

使用您的示例数据:

df = pd.DataFrame({
    't': [1, 2, 3, 4, 5],
    'cash': [100, 90, 50, 120, 40],
    'outflow': [-20, -50, -10, -10, -50]
})

我选择在此函数上使用 pandas apply() 函数,其中 x 是评估行,df 是完整的 DataFrame :

def survival(x, df):
    cash = x['cash']
    i = 0
    while cash > 0:
        try:
            cash = cash + df.loc[x.name + i]['outflow']
            i += 1
        except KeyError:
            print('End of dataframe')
            i += 1
            cash = -1  # To make sure we leave the loop
    return i - 1

然后将它应用到每一行:

df['survival'] = df.apply(survival, args=(df,), axis=1)

# Output

   t  cash  outflow  survival
0  1   100      -20         4
1  2    90      -50         3
2  3    50      -10         2
3  4   120      -10         2
4  5    40      -50         0

正在创建测试数据帧

import pandas as pd
import numpy as np

N = 50
cash = 50 # the initial cash

# I will not type your dataframe
df = pd.DataFrame({'inflow': np.random.randint(1,10, N),
                   'outflow': np.random.randint(1, 20, N)})

那么解决方案可以用

来实现
# computes the cash for each period
ccash = (cash + (df['inflow'] - df['outflow']).cumsum())
survival = (ccash[::-1] >= 0).cumsum()[::-1]