Saya bertanya-tanya bagaimana saya harus membuat bagan garis bertumpuk yang akan mengambil kolom berbeda di matplotlib. Intinya adalah ketika kita melakukan agregasi, saya perlu melakukan agregasi data pada dua kolom yang berbeda, saya pikir saya perlu membuat satu dataframe besar yang akan digunakan untuk plotting. Saya tidak menemukan cara yang lebih cantik dan praktis untuk melakukan ini di pandas, matplotlib. Adakah yang bisa menyarankan kemungkinan tweak untuk melakukan ini? ada ide?

usaha saya

Ini adalah agregasi pertama yang harus saya lakukan:

import pandas as pd
import matplotlib.pyplot as plt

url = "https://gist.githubusercontent.com/adamFlyn/4657714653398e9269263a7c8ad4bb8a/raw/fa6709a0c41888503509e569ace63606d2e5c2ff/mydf.csv"
df = pd.read_csv(url, parse_dates=['date'])

df_re = df[df['retail_item'].str.contains("GROUND BEEF")]
df_rei = df_re.groupby(['date', 'retail_item']).agg({'number_of_ads': 'sum'})
df_rei = df_rei.reset_index(level=[0,1])
df_rei['week'] = pd.DatetimeIndex(df_rei['date']).week
df_rei['year'] = pd.DatetimeIndex(df_rei['date']).year
df_rei['week'] = df_rei['date'].dt.strftime('%W').astype('uint8')

df_ret_df1 = df_rei.groupby(['retail_item', 'week'])['number_of_ads'].agg([max, min, 'mean']).stack().reset_index(level=[2]).rename(columns={'level_2': 'mm', 0: 'vals'}).reset_index()

Dan ini adalah agregasi kedua yang perlu saya lakukan yang mirip dengan yang pertama kecuali saya memilih kolom yang berbeda sekarang:

df_re['price_gap'] = df_re['high_price'] - df_re['low_price']
dff_rei1 = df_re.groupby(['date', 'retail_item']).agg({'price_gap': 'mean'})
dff_rei1 = dff_rei1.reset_index(level=[0,1])
dff_rei1['week'] = pd.DatetimeIndex(dff_rei1['date']).week
dff_rei1['year'] = pd.DatetimeIndex(dff_rei1['date']).year
dff_rei1['week'] = dff_rei1['date'].dt.strftime('%W').astype('uint8')

dff_ret_df2 = dff_rei1.groupby(['retail_item', 'week'])['price_gap'].agg([max, min, 'mean']).stack().reset_index(level=[2]).rename(columns={'level_2': 'mm', 0: 'vals'}).reset_index()

Sekarang saya berjuang bagaimana saya bisa menggabungkan output dari agregasi pertama, kedua menjadi satu kerangka data untuk membuat bagan garis bertumpuk. Apakah itu mungkin untuk dilakukan?

sasaran:

Saya ingin membuat bagan garis bertumpuk di mana sumbu y mengambil kolom yang berbeda seperti sumbu y harus menampilkan # iklan, dan kisaran harga, sedangkan sumbu x menunjukkan periode 52 minggu. Ini adalah sebagian kode yang saya coba buat diagram garis:

for g, d in df_ret_df1.groupby('retail_item'):
    fig, ax = plt.subplots(figsize=(7, 4), dpi=144)
    sns.lineplot(x='week', y='vals', hue='mm', data=d,alpha=.8)
    y1 = d[d.mm == 'max']
    y2 = d[d.mm == 'min']
    plt.fill_between(x=y1.week, y1=y1.vals, y2=y2.vals)
    
    for year in df['year'].unique():
        data = df_rei[(df_rei.date.dt.year == year) & (df_rei.retail_item == g)]
        sns.lineplot(x='week', y='price_gap', ci=None, data=data,label=year,alpha=.8)

Apakah ada cara yang elegan sehingga kami dapat membuat data plot di mana agregasi data pada kolom yang berbeda dapat dilakukan dengan mudah di panda? Apakah ada cara lain untuk membuat ini terjadi? ada pikiran?

keluaran yang diinginkan:

Di sini adalah output yang diinginkan yang ingin saya dapatkan: masukkan deskripsi gambar di sini python pandas matplotlib seaborn

4
kim 7 Mei 2021, 18:54

1 menjawab

Jawaban Terbaik

Fitur groupby Panda sangat fleksibel, dan Anda dapat mengurangi baris kode secara signifikan untuk mencapai kerangka data akhir untuk plot.

plotdf = df_re.groupby([ 'retail_item',df_re['date'].dt.year,df_re['date'].dt.week]).agg({'number_of_ads':'sum','price_gap':'mean'}).unstack().T

Setelah agregasi dilakukan dengan cara yang benar, gunakan for loop untuk menunjukkan setiap langkah yang diperlukan dalam plot yang berbeda. Plot rentang yang diarsir dengan menggunakan fitur deskripsi pandas untuk menghitung min dan maks dengan cepat:

f,axs = plt.subplots(2,1,figsize=(20,14))
axs=axs.ravel()

for i,x in enumerate(['number_of_ads','price_gap']):
    plotdf.loc[x].plot(rot=90,grid=True,ax=axs[i])
    plotdf.loc[x].T.describe().T[['min','max']].plot(kind='area',color=['w','grey'],alpha=0.3,ax=axs[i],title= x)

enter image description here

Edit dengan kode yang diperbarui:

plotdf = df_re.groupby(['retail_item',df_re['date'].dt.year,df_re['date'].dt.week]).agg({'number_of_ads':'sum','weighted_avg':'mean'}).unstack().T
f,axs = plt.subplots(3,2,figsize=(20,14))
axs=axs.ravel()
i=0
for col in plotdf.columns.get_level_values(0).unique():
    for x in ['number_of_ads','weighted_avg']:
        plotdf.loc[x,col].plot(rot=90,grid=True,ax=axs[i]);
      plotdf.loc[x,col].T.describe().T[['min','max']].plot(kind='area',color=['w','grey'],alpha=0.3,ax=axs[i],title= col+', '+x)
        i+=1
2
HMReliable 12 Mei 2021, 18:43