Python 如何使用'在熊猫数据框中使用连续分布按列值范围分组;分组依据';和';切割';方法?

Python 如何使用'在熊猫数据框中使用连续分布按列值范围分组;分组依据';和';切割';方法?,python,pandas,dataframe,range,backend,Python,Pandas,Dataframe,Range,Backend,我有一个熊猫数据框,如下所示,显示石油产品轻柴油的最小、最大和平均销售额,我想从中生成数据框,显示石油产品的最小、最大和平均销售额,间隔5年,如2010-20142015-2019,。。等等,包括最后几年 假设下面数据帧的名称为“lightdiesel_df” 因此,基本上我希望以下输出为: petroleum_product year min_sale max_sale avg_sale Light Diesel Oil 2010-2014 227 258

我有一个熊猫数据框,如下所示,显示石油产品轻柴油的最小、最大和平均销售额,我想从中生成数据框,显示石油产品的最小、最大和平均销售额,间隔5年,如2010-20142015-2019,。。等等,包括最后几年

假设下面数据帧的名称为“lightdiesel_df”

因此,基本上我希望以下输出为:

petroleum_product   year      min_sale  max_sale  avg_sale
Light Diesel Oil    2010-2014   227     258        242.5
Light Diesel Oil    2005-2009   179     377        278
Light Diesel Oil    2000-2004   88     3416       1420.8

尝试使用
Grouper
传递频率(5年)和参数closed='left',如下所示:

df2['year'] = pd.to_datetime(df2['year'], format = '%Y')

(df2.groupby(['petroleum_product', pd.Grouper(key = 'year', freq = '5Y', closed = 'left')])
    .agg(
      {'year': lambda x: '-'.join((str(min(x.dt.year)), str(max(x.dt.year)))),
      'max_sale' : 'max',
      'min_sale' : 'min',
      'avg_sale' : 'mean'
    }).reset_index(level= 0).reset_index(drop=True)
)
#output:

    petroleum_product   year        max_sale    min_sale    avg_sale
0   Light Diesel Oil    2000-2004   3416        88          1420.8
1   Light Diesel Oil    2005-2009   377         179         278.0
2   Light Diesel Oil    2010-2014   258         0           97.0
请试一试

pd.cut用于在特定范围内分割df

df['year_range']=pd.cut(df.year, [1999,2004,2009,2015])

df_res=df.groupby(['petroleum_product','year_range']).agg({'max_sale':'max', 
'min_sale':'min','avg_sale':'mean'})
您还可以在从
年份
列和
标签
创建垃圾箱后尝试使用,以根据预期输出设置格式:

bins=[*range(df['year'].min(),df['year'].max()+5)][::5]
#output : [2000, 2005, 2010, 2015]
labels=[f"{a}-{b-1}" for a,b in zip(bins,bins[1::])]
#output: ['2000-2004', '2005-2009', '2010-2014']
s=pd.cut(df['year'],bins,labels=labels,include_lowest=True,right=False)

final=(df.assign(year=s).groupby(['petroleum_product','year'],sort=False,as_index=False)
 .agg({'max_sale':'max', 'min_sale':'min','avg_sale':'mean'}))


@SuyenShrestha 2010-2014年的最大值是多少227?如果2012年的值为258(检查第3行)@SuyenShrestha,这意味着年份列是字符串列,请首先转换为int或float
df['year']=df['year'].astype(int)
df['year']=pd.to_numeric(df['year'],errors='concurrence')
@SuyenShrestha没问题,如果有效,请检查并评估错误:分类类别必须是唯一的。我遇到此错误不知道原因?@SuyenShrestha在看不到原始数据的情况下很难判断。可能会尝试我认为
“-”。join(…
在这里更好:)不错的解决方案bdw+1您还可以使用格式参数转换为datetime:
pd.to_datetime(df['year',format='%Y')
:)@anky_91 ty作为提示:)@anky_91我从未见过“to_datetime”命令只使用年份格式。我真的很感激这个提示,我今天学到了一些新东西,谢谢:)在计算石油产品的平均值和最小值时,是否可以省略“0”值?例如:在2010-2014年间,如果我们在计算min of min_sale时忽略“0”值,我们得到227,avg of avg_sale为242.5,而不是97。如果在groupby之前将零转换为NaN,我相信代码会满足您的要求,但我现在不在电脑上编辑答案:/
bins=[*range(df['year'].min(),df['year'].max()+5)][::5]
#output : [2000, 2005, 2010, 2015]
labels=[f"{a}-{b-1}" for a,b in zip(bins,bins[1::])]
#output: ['2000-2004', '2005-2009', '2010-2014']
s=pd.cut(df['year'],bins,labels=labels,include_lowest=True,right=False)

final=(df.assign(year=s).groupby(['petroleum_product','year'],sort=False,as_index=False)
 .agg({'max_sale':'max', 'min_sale':'min','avg_sale':'mean'}))
  petroleum_product       year  max_sale  min_sale  avg_sale
0  Light Diesel Oil  2010-2014      3416        88    1420.8
1  Light Diesel Oil  2005-2009       377       179     278.0
2  Light Diesel Oil  2000-2004       258         0      97.0