熊猫动态删除行

时间:2018-08-06 21:55:13

标签: pandas dataframe

我有一个数据集,其中包含account_number,日期,余额,收取的利息和代码。这是会计数据,因此如果数据提供者错误将事务过帐,然后将其撤消,因此可以多次将事务过帐和撤消。

Account_Number   Date        Balance    Interest Charged   Code
0012            01/01/2017   1,000,000     $ 50.00          Posted
0012            01/05/2017   1,000,000     $-50.00          Reversed 
0012            01/07/2017   1,000,000     $ 50.00          Posted
0012            01/10/2017   1,000,000     $-50.00          Reversed
0012            01/15/2017   1,000,000     $50.00           Posted
0012            01/17/2017   1,500,000     $25.00           Posted
0012            01/18/2017   1,500,000     $-25.00          Reversed

查看上面的数据集-我试图找出一种通过帐号和余额查看每一行的方法,如果它们是反向收费,则应删除这两行,并且仅在以下情况下才收费它们没有相应的逆转(2017年1月15日)。例如,2017年1月1日在余额1,000,000上过帐50.00美元的费用,而在2017年5月1日在相同余额上冲销了费用-因此应将这两行都排除在外。 01/07和01/10的情况相同。

我不确定如何解决此问题-任何想法或技巧都很好!

1 个答案:

答案 0 :(得分:0)

所以这样的问题是有很多极端的情况。为它们进行优化的很多或很多不取决于数据的处理方式。话虽如此,这是一种解决方案。假设-

对于每个帐号和余额,每个冲销交易的都在相应的付款之后。

>>import pandas as pd
>>from datetime import date
>>df = pd.DataFrame(data = [
                    ['0012', date(2017, 1, 1), 1000000, 50, 'Posted'],['0012', date(2017, 1, 5), 1000000, -50, 'Reversed'],
                    ['0012', date(2017, 1, 7), 1000000, 50, 'Posted'],['0012', date(2017, 1, 10), 1000000, -50, 'Reversed'], 
                    ['0012', date(2017, 1, 15), 1000000, 50, 'Posted'],['0012', date(2017, 1, 17), 1500000, 25, 'Posted'],
                    ['0012', date(2017, 1, 18), 1500000, -25, 'Reversed'],],
        columns=['Account_Number', 'Date', 'Balance', 'Interest Charged', 'Code'])
>>df
  Account_Number        Date  Balance  Interest Charged      Code
0           0012  2017-01-01  1000000                50    Posted
1           0012  2017-01-05  1000000               -50  Reversed
2           0012  2017-01-07  1000000                50    Posted
3           0012  2017-01-10  1000000               -50  Reversed
4           0012  2017-01-15  1000000                50    Posted
5           0012  2017-01-17  1500000                25    Posted
6           0012  2017-01-18  1500000               -25  Reversed

>> def f(df_g):
    idx = df_g[df_g['Code'] == 'Reversed'].index
    return df_g.loc[~df_g.index.isin(idx.union(idx-1)), ['Date', 'Interest Charged', 'Code']]

>>df.groupby(['Account_Number', 'Balance']).apply(f).reset_index().loc[:, df.columns]
   Account_Number        Date  Balance  Interest Charged    Code
0           0012  2017-01-15  1000000                50  Posted

它是如何工作的-基本上,对于帐号和余额的每个组合,我查看带有反转的行,然后删除它们以及紧挨着它的行。

编辑:-为了使其更加健壮(现在它根据金额,余额和科目编号提取了最后一行:

>>df = pd.DataFrame(data = [
                ['0012', date(2017, 1, 1), 1000000, 53, 'Posted'],['0012', date(2017, 1, 7), 1000000, 50, 'Posted'],['0012', date(2017, 1, 5), 1000000, -50, 'Reversed'],
                ['0012', date(2017, 1, 10), 1000000, -53, 'Reversed'], 
                ['0012', date(2017, 1, 15), 1000000, 50, 'Posted'],['0012', date(2017, 1, 17), 1500000, 25, 'Posted'],
                ['0012', date(2017, 1, 18), 1500000, -25, 'Reversed'],],
    columns=['Account_Number', 'Date', 'Balance', 'Interest Charged', 'Code'])
>>df
  Account_Number        Date  Balance  Interest Charged      Code
0           0012  2017-01-01  1000000                53    Posted
1           0012  2017-01-07  1000000                50    Posted
2           0012  2017-01-05  1000000               -50  Reversed
3           0012  2017-01-10  1000000               -53  Reversed
4           0012  2017-01-15  1000000                50    Posted
5           0012  2017-01-17  1500000                25    Posted
6           0012  2017-01-18  1500000               -25  Reversed

>>output_cols = df.columns
>>df['ABS_VALUE'] = df['Interest Charged'].abs()

>>def f(df_g):
    df_g = df_g.reset_index() # Added this new line
    idx = df_g[df_g['Code'] == 'Reversed'].index
    return df_g.loc[~df_g.index.isin(idx.union(idx-1)), ['Date', 'Interest Charged', 'Code']]

>>df.groupby(['Account_Number', 'Balance', 'ABS_VALUE']).apply(f).reset_index().loc[:, output_cols]
  Account_Number        Date  Balance  Interest Charged    Code
0           0012  2017-01-15  1000000                50  Posted