首页 > 解决方案 > 对 groupby 对象的操作为新数据框的所有列返回单个值

问题描述

我一整天都在试图解决这个问题,但 Stackoverflow 上没有关于这个主题的任何内容。

我正在对 groupby 对象进行计算,但输出已关闭。我假设我使用 apply 方法有问题,但无法弄清楚这是我的玩具数据集来说明我的问题:

data1 = pd.DataFrame({'Id' : ['001','001','001','001','001','001','001','001','001',
                              '002','002','002','002','002','002','002','002','002',],
                      'Date': ['2020-01-12', '2019-12-30', '2019-12-01','2019-11-01', '2019-08-04', '2019-08-04', '2019-08-01', '2019-07-20', '2019-06-04',
                               '2020-01-11', '2019-12-12', '2019-12-01','2019-12-01', '2019-09-10', '2019-08-10', '2019-08-01', '2019-06-20', '2019-06-01'],
                      'Quantity' :[4,5,6,8,12,14,16,19,20,           8,7,6,5,4,3,2,1,0]
                      })

我的代码如下所示:

today_month = int(time.strftime("%m"))
data1['Date'] =pd.to_datetime(data1['Date'])
data1 = data1[data1.Id.apply(lambda x: x.isnumeric())]
data2 = data1.groupby('Id').apply(lambda x: x.set_index('Date').resample('M').sum())


forecast = pd.DataFrame()
forecast['Id'] = data1['Id'].unique()
data3 = data2.groupby(level='Id').tail(5)


forecast['trendup'] = data3.apply(lambda x: data3['Quantity'].is_monotonic_increasing).sum()
forecast['trenddown'] = data3.apply(lambda x: data3['Quantity'].is_monotonic_decreasing).sum()

forecast['trend_status'] = np.where(~(forecast['trendup'] | forecast['trenddown']), 'Not_trending', 'trending')
forecast['L0'] = data3.apply(lambda x: data3['Quantity'].mean()).sum()

输出是这样的:

    Id  trendup  trenddown  trend_status   L0
0  001        0          0  Not_trending  5.3
1  002        0          0  Not_trending  5.3

更新:所需的输出是:

    Id  trendup  trenddown  trend_status    L0
0  001     True      False      trending  12.3
1  002    False      False  Not_trending  13.0


这是这段代码的目标:

目标是为预测方法准备包括几种产品的数据(如果发现趋势,则使用 Holts 方法,如果没有趋势,则使用 E​​S)。为此,我通过 is_monotonic 函数检查连续趋势,然后我使用输出数据框来收集哪个项目是趋势或没有,以便决定使用哪个模型。L0 是预测的 T0 时间,对应于有尾数据帧中最早的月份。

首先,我很困惑为什么“is_monotonic”在输出数据帧中不返回“真或假”而是0。其次,我不明白为什么 L0 返回所有数据集的平均值,而不是每个 groupby 对象组的平均值。

我的 python 级别非常有限,我已经没有办法尝试解决这个问题了。对此的任何帮助都会令人惊叹!

标签: pythonpandas

解决方案


IIUC - 尽管结果似乎并不接近:

data1=data1.sort_values("Date", axis=0, ascending=False)
data1["obs"]=data1.groupby("Id").cumcount()

data2=data1.loc[data1["obs"]<5].groupby("Id").apply(lambda x: pd.Series({"trendup": x["Quantity"].is_monotonic_increasing, "trenddown": x["Quantity"].is_monotonic_decreasing, "LO": x["Quantity"].mean()}))

data2["trend_status"]=np.where(np.logical_or(data2["trendup"], data2["trenddown"]), "trending", "Not_trending")

输出:

     trendup  trenddown   LO trend_status
Id
001     True      False  7.0     trending
002    False       True  6.0     trending

推荐阅读