Python 如何使用'在熊猫数据框中使用连续分布按列值范围分组;分组依据';和';切割';方法?
我有一个熊猫数据框,如下所示,显示石油产品轻柴油的最小、最大和平均销售额,我想从中生成数据框,显示石油产品的最小、最大和平均销售额,间隔5年,如2010-20142015-2019,。。等等,包括最后几年 假设下面数据帧的名称为“lightdiesel_df” 因此,基本上我希望以下输出为: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
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