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=2
中survival = 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]
我有一个包含现金、流入和流出的 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=2
中survival = 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]