Python 有没有更好的方法在同一数据帧上聚合多个列?

Python 有没有更好的方法在同一数据帧上聚合多个列?,python,pandas,matplotlib,Python,Pandas,Matplotlib,我试图弄清楚我应该如何操作我的数据,这样我就可以在多个列上聚合,但对于相同的分组数据。我之所以这样做是因为,我需要得到叠加折线图,它从相同分组数据的不同聚合中获取数据。我们怎样才能做到这一点呢?有人能提出在熊猫身上做这件事的可能方法吗?有什么想法吗 我当前的尝试: import pandas as pd import matplotlib.pyplot as plt url = "https://gist.githubusercontent.com/adamFlyn/46577146

我试图弄清楚我应该如何操作我的数据,这样我就可以在多个列上聚合,但对于相同的分组数据。我之所以这样做是因为,我需要得到叠加折线图,它从相同分组数据的不同聚合中获取数据。我们怎样才能做到这一点呢?有人能提出在熊猫身上做这件事的可能方法吗?有什么想法吗

我当前的尝试

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()
同样,我也需要这样做数据聚合:

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()
问题

当我进行数据聚合时,这些行是相似的:

df_rei = df_re.groupby(['date', 'retail_item']).agg({'number_of_ads': 'sum'})
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()

我认为更好的方法可能是,我必须使用
*arg
**kwargs
来定制函数,以改变聚合列的方式,但我应该如何显示y轴显示不同数量的堆叠折线图。在
pandas
中可以这样做吗

线图

我为得到折线图做了如下准备:

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, palette=cmap,label=year,alpha=.8)

我想最小化这些,这样我就可以在不同的列上进行聚合,并制作堆叠的折线图,其中它们以周为单位共享x轴,y轴分别显示广告数量和价格范围。我不知道有没有更好的办法。我这样做是因为堆叠折线图(两个垂直子图),一个显示y轴上的广告数量,另一个显示52周内相同商品的价格范围。有人能提出任何可行的方法吗?有什么想法吗?

我不确定这是否完全回答了你的问题,但根据你的标题,我想这一切归结为:

import pandas as pd

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

# define which columns to group and in which way
dct = {'low_price': [max, min],
       'high_price': min,
       'year': 'mean'}

# actually group the columns
df.groupby(['region']).agg(dct)
输出:

              low_price       high_price         year
                    max   min        min         mean
region
ALASKA            16.99  1.33       1.33  2020.792123
HAWAII            12.99  1.33       1.33  2020.738318
MIDWEST           28.73  0.99       0.99  2020.690159
NORTHEAST         19.99  1.20       1.99  2020.709916
NORTHWEST         16.99  1.33       1.33  2020.736397
SOUTH CENTRAL     28.76  1.20       1.49  2020.700980
SOUTHEAST         21.99  1.33       1.48  2020.699655
SOUTHWEST         16.99  1.29       1.29  2020.704341

这个答案建立在Andreas的基础上,他已经回答了如何以紧凑的方式生成多个列的聚合变量这一主要问题。这里的目标是专门针对您的案例实施该解决方案,并给出一个如何从聚合数据生成单个图形的示例。以下是一些要点:

  • 原始数据集中的日期已经是每周频率,因此
    groupby('week')
    不需要
    df_ret_df1
    dff_ret_df2
    ,这就是为什么它们包含相同的最小值、最大值和平均值
  • 此示例使用pandas和matplotlib,因此不需要像使用seaborn时那样堆叠变量
  • 聚合步骤为列生成多索引。您可以使用访问每个高级变量的聚合变量(最小值、最大值、平均值)
  • 日期设置为聚合数据帧的索引,用作x变量。使用DatetimeIndex作为x变量,可以更灵活地格式化刻度标签,并确保数据始终按时间顺序打印
  • 在这个问题上,不清楚如何显示不同年份的数据(在单独的数字中?),因此这里整个时间序列显示在一个单独的数字中

导入数据集并根据需要进行聚合

作为pd导入熊猫#v 1.2.3
将matplotlib.pyplot作为plt#v 3.3.4导入
#导入数据集
url='1〕https://gist.githubusercontent.com/adamFlyn/4657714653398e9269263a7c8ad4bb8a/\
raw/fa6709a0c41888503509e569ace63606d2e5c2ff/mydf.csv'
df=pd.read\u csv(url,parse\u dates=['date'])
#创建包含碎牛肉产品数据的数据框,计算
#聚合变量,并将日期设置为索引
df_gbeef=df[df['retail_item'].str.contains('GROUND BEEF')].copy()
df_gbeef[‘价格差距’]=df_gbeef[‘高价’]-df_gbeef[‘低价’]
agg_dict={'number_of_ads':[min,max',mean'],
‘价格差距’:[min,max,'mean']}
df_gbeef_agg=(df_gbeef.groupby(['date','retail_item')).agg(agg_dict)
.reset_索引(“零售_项目”)
df_gbeef_agg


以包含小倍数的单个图形绘制聚合变量

variables=['广告数量','价格差距']
颜色=['标签:橙色','标签:蓝色']
nrows=len(变量)
ncols=df_gbeef_agg['retail_item'].nunique()
图,axs=plt.subplot(nrows,ncol,figsize=(10,5),sharex=True,sharey='row')
对于axs_行、变量、zip中的颜色(axs、变量、颜色):
对于枚举(df_gbeef_agg.groupby('retail_item'))中的i(item,df_item):
ax=axs_行[i]
#选择数据并绘制它
数据=df_item.xs(变量,轴=1)
ax.fill_介于(x=data.index,y1=data['min',y2=data['max'])之间,
颜色=颜色,alpha=0.3,标签='min/max')
ax.plot(data.index,data['mean'],color=color,label='mean')
ax.脊椎['bottom'].设置位置('zero')
#设置x轴刻度标签的格式
fmt=plt.matplotlib.dates.DateFormatter('%W')#不等于ISO week
ax.xaxis.set\u major\u格式化程序(fmt)
#根据图中位置的Fomat子批次
如果ax.是第一行():
ax.设置标题(项目,pad=10)
如果ax.是最后一行():
ax.set_xlabel('周数',大小=12,labelpad=5)
如果ax.is_first_col():
ax.set_ylabel(变量,大小=12,labelpad=10)
如果ax.is_last_col():
ax.图例(frameon=False)
图suptitle(“碎牛肉产品的跨区域每周广告和价格差距”,
尺寸=14,y=1.02)
图:子批次调整(hspace=0.1);

谢谢你提醒我,但这不是我的意思。有可能的更新吗?@kim是的,可能,你能试着把你的问题归结到最基本的部分吗?因为我猜未来的读者可能也会有同样的问题,但如果问题和样本太大,就不会轻易发现。是的,我想说的是,我们有任何方法可以将
number\u广告
列和
price\u范围
列聚合在一起,按
日期
零售项目
进行分组。在我的尝试中,我不得不做两次,相反,我们能做一些更好的事情吗?这里有很多数据帧。
              low_price       high_price         year
                    max   min        min         mean
region
ALASKA            16.99  1.33       1.33  2020.792123
HAWAII            12.99  1.33       1.33  2020.738318
MIDWEST           28.73  0.99       0.99  2020.690159
NORTHEAST         19.99  1.20       1.99  2020.709916
NORTHWEST         16.99  1.33       1.33  2020.736397
SOUTH CENTRAL     28.76  1.20       1.49  2020.700980
SOUTHEAST         21.99  1.33       1.48  2020.699655
SOUTHWEST         16.99  1.29       1.29  2020.704341