遍历数据框时修改行值的值

时间:2019-03-01 01:22:49

标签: python pandas iterator

我有这个数据框test_data:

  Deal    Year    Month     Billing   Running_total   payment    over_payment

2   A      2018   December  21167.99    21167.99      1270.08       0.00
3   A      2018   December  -3184.59    17983.40     -1270.08       0.00
4   A      2019   January   1855.10     19838.50      0.00      -1270.08
5   A      2019   February  400.00      20238.50      0.00          0.00
6   A      2019   March     600.00      20838.50      0.00          0.00
7   A      2019   April     1000.00     21838.50      0.00          0.00

只要Runing_total的6%小于-1270的绝对值,我要一直将超额付款中的负数向下传递到下一行,直到Running_total的6%大于或等于6%。 over_payment的绝对值,然后将over_payment的值设置为0。在获得正确的输出之前,我必须执行以下四次代码,我认为在迭代甚至达到该值之前设置over_payment的下一行值必定是一个问题索引#。我正在尝试在“交易”级别执行此操作,这就是为什么我包含一个条件,即下一个交易名称必须等于当前交易名称,因此不会延续到交易“ B” ,并且仅对相关交易进行更改。

这是我尝试过的:

 for index, row in test_data.iterrows():
   if row['over_payment'] <0:
     if (row['Running_Total'] * .06)>abs(row['over_payment']):
       test_data.at[index, 'over_payment']= 0
       test_data.at[index, 'Rebate']= (row['Running_Total'] * .06) + (row['over_payment'])

     elif (row['Running_Total'] * .06)< abs(row['over_payment']):
       next_index= str(int(index) + 1)
       last_index= str(int(index) - 1)
       if test_data.at[index, 'Deal'] ==test_data.at[next_index, 'Deal']:
         test_data.at[next_index, 'over_payment'] = test_data.at[index, 'over_payment']
       else:
         test_data.at[index, 'over_payment'] = test_data.at[last_index, 'over_payment']

所需的输出:

Deal      Year    Month     Billing   Running_total   payment    over_payment

2   A      2018   December  21167.99    21167.99      1270.08       0.00
3   A      2018   December  -3184.59    17983.40      -1270.08      0.00
4   A      2019   January   1855.10     19838.50       0            -1270.08
5   A      2019   February  400.00      20238.50       0            -1270.08
6   A      2019   March     600.00      20838.50       0            -1270.08
7   A      2019   April     1000.00     21838.50       40.23            0

1 个答案:

答案 0 :(得分:0)

以下是一次即可获得所需答案的方法:

for deal in test_data.Deal.unique():
    over_payment = 0  # reset for each deal
    for idx, row in test_data[test_data.Deal == deal].iterrows():
        if row.over_payment < 0:
            over_payment = row.over_payment
        elif over_payment < 0:
            if row.Running_total * 0.06 < abs(over_payment):
                test_data.loc[idx, 'over_payment'] = over_payment
            else:
                over_payment = 0

这里有两个假设。首先是索引是唯一的。第二个是数据按日期顺序排列。两者都很容易管理,您只需要了解它们即可。

我也看不到您对'Rebate'所做的事情,因为这不在您的所需输出中。我也不知道您在向前和向后浏览时遇到什么问题。通过一次只处理一行,而仅保留最后一行的状态,并根据需要对其进行重置,我避免了这种情况。