pandas 基于具有重复值的条件的累积平均值

ryhaxcpt  于 2023-03-21  发布在  其他
关注(0)|答案(1)|浏览(143)

我有一个具有以下结构的DataFrame:

df = pd.DataFrame({
    "item": [1, 1, 1, 1, 2, 2, 2],
    "order": [1, 2, 2, 3, 1, 2, 3],
    "rating": [3, 2, 1, 5, 5, 2, 3]
})

我想计算每个项目的累积平均评分,具体取决于顺序。问题是可能存在重复的顺序。累积平均值只应针对顺序小于当前行的所有行计算。因此,当前顺序不应计入累积平均值。对于顺序相等的所有行,累积平均值应相同。结果应如下所示:
| 项目|订单|额定值|加平均|
| - ------|- ------|- ------|- ------|
| 1个|1个|三个| np.nan |
| 1个|第二章|第二章|三个|
| 1个|第二章|1个|三个|
| 1个|三个|五个|第二章|
| 第二章|1个|五个| np.nan |
| 第二章|第二章|第二章|五个|
| 第二章|三个|三个|三、五|
我目前有一个解决方案,将dataframe转换为一个字典,字典中的项目作为键,列(order,rating)作为列表,迭代每个项目,然后将其转换回df,就像下面这样:

prev_mean_list = []
i = 0
while i < len(_item["rating"]):
    cur_index = _item["order"][i]

    if i == 0:
        prev_mean = np.nan
    elif cur_index == _item["order"][i-1]:
        prev_mean = prev_mean_list[-1]
    else:
        prev_mean = statistics.mean(_item["rating"][0:i])

    prev_mean_list.append(prev_mean)

    i += 1

_item["prev_mean_order"] = prev_mean_list

解决方案工作,但相当慢,因为完整的dataframe由超过200万行组成。我试图用groupBy和expanding创建一个pandas本地解决方案,但失败了。
你能建议一个运行时更好的解决方案吗?

kgsdhlau

kgsdhlau1#

使用numpy broadcasting为不太像实际值的过滤器行创建自定义函数,传递到numpy.where并通过numpy.nanmean获得平均值:

def f(x):
    a = x['order'].to_numpy()
    x['cum_mean'] = np.nanmean(np.where(a < a[:, None], x['rating'], np.nan), axis=1)
    return x

df = df.groupby('item').apply(f)
print (df)
   item  order  rating  cum_mean
0     1      1       3       NaN
1     1      2       2       3.0
2     1      2       1       3.0
3     1      3       5       2.0
4     2      1       5       NaN
5     2      2       2       5.0
6     2      3       3       3.5

相关问题