Python 迭代行并根据现有dataframe列中的条件应用函数
我有以下脚本:Python 迭代行并根据现有dataframe列中的条件应用函数,python,pandas,if-statement,lambda,Python,Pandas,If Statement,Lambda,我有以下脚本: df = pd.DataFrame() df["Stake"]=[0.25,0.15,0.26,0.30,0.10,0.40,0.32,0.11,0.20,0.25] df["Odds"]=[2.5,4.0,1.75,2.2,1.85,3.2,1.5,1.2,2.15,1.65] df["Ftr"]=["H","D","A","H","H","A","D","H","H","A"] df["Ind"]=[1,2,2,1,3,3,3,1,2,2] 其结果是: Stake
df = pd.DataFrame()
df["Stake"]=[0.25,0.15,0.26,0.30,0.10,0.40,0.32,0.11,0.20,0.25]
df["Odds"]=[2.5,4.0,1.75,2.2,1.85,3.2,1.5,1.2,2.15,1.65]
df["Ftr"]=["H","D","A","H","H","A","D","H","H","A"]
df["Ind"]=[1,2,2,1,3,3,3,1,2,2]
其结果是:
Stake Odds Ftr Ind
0 0.25 2.50 H 1
1 0.15 4.00 D 2
2 0.26 1.75 A 2
3 0.30 2.20 H 1
4 0.10 1.85 H 3
5 0.40 3.20 A 3
6 0.32 1.50 D 3
7 0.11 1.20 H 1
8 0.20 2.15 H 2
9 0.25 1.65 A 2
我想另外创建两列“开始余额”和“结束余额”。索引0中的“开始余额”等于1000。“期末余额”始终等于:
"Start Balance" - "Stake" * "Start Balance" + "Stake" x "Start Balance" x "Odds" if column "Ftr" = "H".
或者
然后下一个索引“开始余额”变为前一个索引“结束余额”。例如,索引0中的“结束余额”变为索引1中的“开始余额”
为了使事情变得更加复杂,“开始平衡”应该尊重另外一个条件。如果“Ind”列不同于1,例如2,则两行(索引1和2)的“开始余额”等于索引0中的“结束余额”。同样,如果“Ind”为3,则所有指数(4,5,6)的“开始余额”应等于指数3中的“结束余额”。预期结果是:
Stake Odds Ftr Ind Start Balance End Balance
0 0.25 2.5 H 1 1000.0 1375.0
1 0.15 4 D 2 1375.0 1168.8
2 0.26 1.75 A 2 1375.0 1017.5
3 0.3 2.2 H 1 1017.5 1383.8
4 0.1 1.85 H 3 1383.8 1501.4
5 0.4 3.2 A 3 1383.8 830.3
6 0.32 1.5 D 3 1383.8 941.0
7 0.11 1.2 H 1 941.0 961.7
8 0.2 2.15 H 2 961.7 1182.9
9 0.25 1.65 A 2 961.7 721.3
我没有尝试过任何东西,因为我真的不知道如何处理这么多的条件:)。干杯我想不出一个矢量化函数来做你想做的事情,所以我能想到的唯一解决方案是
for
循环:
# A temp dataframe to keep track of the End Balance by Ind
# It's empty to start
tmp = pd.DataFrame(columns=['index', 'End Balance']).rename_axis('ind')
for index, row in df.iterrows():
stake, odds, ind = row['Stake'], row['Odds'], row['Ind']
if index == 0:
start_balance = 1000
elif row['Ind'] == 1:
start_balance = df.loc[index - 1, 'End Balance']
else:
start_balance = tmp.query('ind != @ind').sort_values('index')['End Balance'].iloc[-1]
end_balance = start_balance * (1 - stake + stake * odds) if row['Ftr'] == 'H' else start_balance * (1 - stake)
# Keep track of when the current Ind last occurs
tmp.loc[ind, ['index', 'End Balance']] = [index, end_balance]
df.loc[index, 'Start Balance'] = start_balance
df.loc[index, 'End Balance'] = end_balance
结果:
Stake Odds Ftr Ind Start Balance End Balance
0 0.25 2.50 H 1 1000.000000 1375.000000
1 0.15 4.00 D 2 1375.000000 1168.750000
2 0.26 1.75 A 2 1375.000000 1017.500000
3 0.30 2.20 H 1 1017.500000 1383.800000
4 0.10 1.85 H 3 1383.800000 1501.423000
5 0.40 3.20 A 3 1383.800000 830.280000
6 0.32 1.50 D 3 1383.800000 940.984000
7 0.11 1.20 H 1 940.984000 961.685648
8 0.20 2.15 H 2 961.685648 1182.873347
9 0.25 1.65 A 2 961.685648 721.264236
事实上,这不是一个错误,而是让我为之奋斗的条件之一。如果“Ind”列不同于1,例如2,则出现2的两行的“开始余额”应等于2之前行的结束余额。在示例中,索引1和索引2的“起始余额”应为“索引0的结束余额”。同样,如果“Ind”列为3,则所有3的行的“起始余额”应等于3前一行的“结束余额”(表中-索引4、5、6的“起始余额”应等于索引3中的“结束余额”)。您提供的解决方案非常接近,但还没有:),无论如何,请让我看看我是否正确理解您的问题:如果
Ind==1
,开始余额=上一行的结束余额。如果Ind==2
,开始余额=最后一行的结束余额Ind!=2
。如果Ind==3
,开始余额=结束余额最后一行的Ind!=3
?这就是你的意思吗?正是我的意思,是的,它只需要在循环中进行一些小的修改。请参阅我编辑的答案
Stake Odds Ftr Ind Start Balance End Balance
0 0.25 2.50 H 1 1000.000000 1375.000000
1 0.15 4.00 D 2 1375.000000 1168.750000
2 0.26 1.75 A 2 1375.000000 1017.500000
3 0.30 2.20 H 1 1017.500000 1383.800000
4 0.10 1.85 H 3 1383.800000 1501.423000
5 0.40 3.20 A 3 1383.800000 830.280000
6 0.32 1.50 D 3 1383.800000 940.984000
7 0.11 1.20 H 1 940.984000 961.685648
8 0.20 2.15 H 2 961.685648 1182.873347
9 0.25 1.65 A 2 961.685648 721.264236