Jak równie zmniejszyć wartość po zgrupowanie?

głosy
2

Mam tabelę, w której niektóre wartości należą do indeksu i niektóre inne należą do powtarzających się wartości. W przykładzie sidjest wskaźnik koszty beolng do sid, ale jeden sid może zawierać wiele transakcji i jeszcze jedna transakcja może zawierać wiele kategorii.

df = pd.DataFrame([
    [1, 100, 1, 'A', 1, 50, 2],
    [1, 100, 2, 'A', 1, 50, 1],
    [1, 100, 2, 'B', 2, 100, 1],
    [1, 100, 2, 'C', 3, 50, 1],
    [2, 200, 3, 'D', 4, 500, 1],
    [2, 200, 4, 'C', 2, 100, 1],
    [3, 200, 5, 'B', 2, 100, 1],
    [3, 200, 5, 'A', 1, 50, 1],
    [3, 200, 5, 'A', 3, 50, 1]
], columns=['sid', 'costs', 'transaction_id', 'category', 'sku', 'price', 'quantity'])

df['revenue'] = df['price'] * df['quantity']

Więc jeśli patrzeć na poziomie sid muszę przyjąć pierwszą wartość sumy kosztów i przychodów. To w jaki sposób należy to wygląda. Koszty ogółem - 500, całkowite dochody - 1100.

df.groupby('sid').agg({'costs': 'min', 'revenue':'sum'}).pivot_table(index='sid', margins=True, aggfunc='sum')  

wprowadzić

Ale chcę rozkładać sid według kategorii. Mogę zrobić to w ten sposób.

df.groupby(['sid', 'category']).agg({'costs': 'min', 'revenue':'sum'}).pivot_table(index=['sid', 'category'], aggfunc='sum', margins=True)

wprowadzić

Moim problemem jest to, że dla każdego wiersza koszty były powielane. I suma kosztów wynosi 1100, co nie jest prawdą. Chcę równie zmniejszyć koszty odnośnie do ilości w każdej kategorii sid. Więc to wygląda

wprowadzić

Czy możliwe jest zastosowanie takiej funkcji toczenia?

Utwórz 18/12/2018 o 11:02
źródło użytkownik
W innych językach...                            


2 odpowiedzi

głosy
3

Oto coś można zrobić:

g = df.groupby(['sid', 'category']).agg({'revenue':'sum', 'costs': 'min'})
div = df.groupby(['sid'])['category'].nunique()
g['costs'] = g['costs']/div

                revenue     costs
sid category                     
1   A             150   33.333333
    B             100   33.333333
    C              50   33.333333
2   C             100  100.000000
    D             500  100.000000
3   A             100  100.000000
    B             100  100.000000

A dla ostatniego rzędu, w tym sumz dwóch kolumnach po prostu dodać jeszcze na koniec:

g.pivot_table(index=['sid', 'category'], aggfunc='sum', margins=True)
Odpowiedział 18/12/2018 o 11:33
źródło użytkownik

głosy
2

Myślę, że trzeba podzielić liczbę sidza grup utworzonych przez transformi size:

df = df.groupby(['sid', 'category']).agg({'costs': 'min', 'revenue':'sum'})
df['costs'] = df['costs'].div(df.groupby('sid')['costs'].transform('size'))
df = df.pivot_table(index=['sid', 'category'], aggfunc='sum', margins=True)
print (df)
                   costs  revenue
sid category                     
1   A          33.333333      150
    B          33.333333      100
    C          33.333333       50
2   C         100.000000      100
    D         100.000000      500
3   A         100.000000      100
    B         100.000000      100
All           500.000000     1100
Odpowiedział 18/12/2018 o 11:32
źródło użytkownik

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more