Условное вычитание строк в Dataframe Python Pandas - PullRequest
0 голосов
/ 08 сентября 2018

Я пытаюсь решить проблему под рукой, как объяснено. У меня есть датафрейм, как показано ниже:

Date    Item    Type    Qty Price
1/1/18  Orange  Add     100 25
5/1/18  Orange  Add     20  40
8/1/18  Orange  Add     40  20
18/1/18 Orange  Add     10  35
27/2/18 Orange  Sub     100 55
15/4/18 Orange  Sub     30  45

и я хочу получить промежуточный фрейм данных, как показано ниже:

Date    Item    Type    Qty Price   Diff
1/1/18  Orange  Add     0   25      30
5/1/18  Orange  Add     0   40      5
8/1/18  Orange  Add     30  20      25
18/1/18 Orange  Add     10  35

и затем окончательный Dataframe. Я хочу, чтобы это было так, как показано ниже:

Date    Item    Type    Qty Price
8/1/18  Orange  Add     30  20
18/1/18 Orange  Add     10  35

ПРИМЕЧАНИЕ. Разница - это разница между Sub и Add Price. И Qty также обновляется с помощью Qty of Sub, вычитаемого из Qty of Add.

Может кто-нибудь из вас, пожалуйста, помочь с тем, как это может быть достигнуто. Я пытался с групповым, применить и преобразовать, но до сих пор у меня нет этого.

У меня есть код ниже, все еще в разработке и не завершен:

def FruitSummary():
    df = pd.DataFrame([
               ['01/1/18',   'Orange',   'Add',  100,    25],
               ['05/1/18',   'Orange',   'Add',   20,    40],
               ['08/1/18',   'Orange',   'Add',   40,    20],
               ['18/1/18',   'Orange',   'Add',   10,    35],
               ['27/2/18',   'Orange',   'Sub',  100,    55],
               ['15/4/18',   'Orange',   'Sub',   30,    45],
               ['02/1/18',   'Banana',   'Add',  110,     7],
               ['04/1/18',   'Banana',   'Add',   20,     9],
               ['11/1/18',   'Banana',   'Add',   40,     4],
               ['10/2/18',   'Banana',   'Add',   10,     3],
               ['15/3/18',   'Banana',   'Sub',  100,     9],
               ['15/4/18',   'Banana',   'Sub',   50,     8],
               ['10/3/18',   'Kiwi',     'Add',   80,    29],
               ['12/3/18',   'Berry',    'Add',   25,     5],
               ['18/4/18',   'Berry',    'Add',   15,     8]],
       columns=['Date',      'Item',     'Type', 'Qty',  'Price'])

    print(df)

    def fruit_stat(dfIN):
        print(dfIN)
        print((dfIN['Type'] == 'Sub').unique(), (dfIN['Type'] == 'ODD').unique())

        if len(dfIN) > 1 and (True in (dfIN['Type'] == 'Sub').unique()):
            print(dfIN['Item'].iloc[1], "'len > 1'", "'Sub True'")

dfFS = df.groupby(['Item']).apply(fruit_stat)
print(dfFS)

1 Ответ

0 голосов
/ 08 сентября 2018

Я могу найти какое-то решение, но не уверен, что оно оптимально или может быть лучшее решение для того же.

df = pd.DataFrame([['01/1/18',   'Orange',   'Add',  100,    25],
                   ['05/1/18',   'Orange',   'Add',   20,    40],
                   ['08/1/18',   'Orange',   'Add',   40,    20],
                   ['18/1/18',   'Orange',   'Add',   10,    35],
                   ['27/2/18',   'Orange',   'Sub',  100,    55],
                   ['15/4/18',   'Orange',   'Sub',   30,    45],
                   ['02/1/18',   'Banana',   'Add',  110,     7],
                   ['04/1/18',   'Banana',   'Add',   20,     9],
                   ['11/1/18',   'Banana',   'Add',   40,     4],
                   ['10/2/18',   'Banana',   'Add',   10,     3],
                   ['15/3/18',   'Banana',   'Sub',  100,     9],
                   ['15/4/18',   'Banana',   'Sub',   50,     8],
                   ['10/3/18',   'Kiwi',     'Add',   80,    29],
                   ['12/3/18',   'Berry',    'Add',   25,     5],
                   ['18/4/18',   'Berry',    'Add',   15,     8],
                   ['16/3/18',   'Cherry',   'Add',   25,     5],
                   ['21/4/18',   'Cherry',   'Sub',   25,     8],
                   ['19/3/18',   'Grapes',   'Add',   25,     5],
                   ['23/4/18',   'Grapes',   'Sub',   15,     8]],
          columns=['Date',      'Item',     'Type', 'Qty',  'Price'])


def FruitSummary(df):
    df['CumSum'] = df.groupby(['Item', 'Type'])['Qty'].cumsum()
    print(df)

    def fruit_stat(dfg):
        if dfg[dfg['Type'] == 'Sub']['Qty'].count():
            subT = dfg[dfg['Type'] == 'Sub']['CumSum'].iloc[-1]
            dfg['Qty'] = np.where((dfg['CumSum'] - subT) <= 0, 0, dfg['Qty'])
            dfg = dfg[dfg['Qty'] > 0]
            if(len(dfg) > 0):
                dfg['Qty'].iloc[0] = dfg['CumSum'].iloc[0] - subT

        return dfg

    dfFS = df.groupby(['Item'], as_index=False).apply(fruit_stat).drop(['CumSum'], axis=1).reset_index(drop=True)
    print(dfFS)

И приведенный выше код выдает ответ, подобный приведенному ниже:

      Date    Item Type  Qty  Price
0  11/1/18  Banana  Add   20      4
1  10/2/18  Banana  Add   10      3
2  12/3/18   Berry  Add   25      5
3  18/4/18   Berry  Add   15      8
4  19/3/18  Grapes  Add   10      5
5  10/3/18    Kiwi  Add   80     29
6  08/1/18  Orange  Add   30     20
7  18/1/18  Orange  Add   10     35
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...