You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL中带amount列时如何计算selling_eur的中位数?

如何计算带数量权重的selling_eur中位数?

数据集

索引idlisting_idcategoryamountoriginal_eurselling_euruser_idrounds_id
010088m1-1579cd77-6863-469d-8798-9e1bef199d2fCategory 22nan350.11eu-central-1:6fcfad76-ef06-4ea6-9e14-9fa4a5d62b8f31
110089m1-2adfde90-de27-4048-aa3e-bc7e76c03b0cPrime Seats4nan962.81eu-central-1:6fcfad76-ef06-4ea6-9e14-9fa4a5d62b8f28
210090m3-024c20ad-e21d-4bb3-966e-44c69e760b15Category 14200750eu-central-1:33d3dbe4-6414-4949-ae21-f2bc8819ae4d29
310091m1-c612ad6c-d000-4bb5-8dc4-55e3b49d54cdCategory 24150450eu-central-1:fe695442-13a6-42e6-a015-046415bf369d28
410092m1-cd449fb2-6134-428b-946a-fc8a7bec30e7Category 14nan647eu-central-1:b926a781-4fc0-4f71-bd0f-69b50b0be68d28

问题描述

已知加权平均的计算方式为:sum(selling_eur * amount) / sum(amount),但不清楚如何计算带数量权重的中位数,同时询问是否可以通过生成包含重复价格的数组(比如第一行生成[350.11, 350.11])来计算中位数。


解决方案

1. 生成重复数组的思路完全可行

这种方法严格贴合中位数的定义:将所有单个数据点排序后,取中间值(或中间两个值的平均)。针对当前数据集:

  • 展开所有数据点:[350.11, 350.11, 962.81, 962.81, 962.81, 962.81, 750, 750, 750, 750, 450, 450, 450, 450, 647, 647, 647, 647]
  • 排序后:[350.11, 350.11, 450, 450, 450, 450, 647, 647, 647, 647, 750, 750, 750, 750, 962.81, 962.81, 962.81, 962.81]
  • 总数据量为2+4+4+4+4=18(偶数),中位数为第9和第10个值的平均:(647 + 647)/2 = 647

但这种方法在数据量较大时(比如amount值很大或行数极多)会占用过多内存,更高效的方式是用权重直接计算。

2. 高效的加权中位数计算方法(无需展开数组)

步骤如下:

  1. 按selling_eur从小到大排序数据集
  2. 计算累计amount,找到累计量达到总数量一半(或中间位置)的区间
  3. 根据累计量的位置确定中位数

针对当前数据集的计算过程:

  • 总数量:sum(amount) = 18,中间位置为第9和第10个数据点
  • 排序后的数据集及累计amount:
    selling_euramount累计amount
    350.1122
    45046
    647410
    750414
    962.81418
  • 第9和第10个数据点都落在selling_eur=647的区间内,因此中位数为647

3. Python代码实现(Pandas)

如果用Pandas处理,可以选择两种方式:

import pandas as pd

# 构造数据集
data = {
    'selling_eur': [350.11, 962.81, 750, 450, 647],
    'amount': [2, 4, 4, 4, 4]
}
df = pd.DataFrame(data)

# 方法1:展开数组计算(适合小数据集)
expanded_values = df.loc[df.index.repeat(df['amount']), 'selling_eur']
median_expanded = expanded_values.median()
print(f"展开数组计算的中位数:{median_expanded}")

# 方法2:加权中位数计算(高效)
df_sorted = df.sort_values('selling_eur')
df_sorted['cum_amount'] = df_sorted['amount'].cumsum()
total_count = df_sorted['cum_amount'].iloc[-1]
median_position = total_count / 2

# 定位包含中位数位置的行
median_row = df_sorted[df_sorted['cum_amount'] >= median_position].iloc[0]
median_weighted = median_row['selling_eur']
print(f"加权计算的中位数:{median_weighted}")

运行结果:

展开数组计算的中位数:647.0
加权计算的中位数:647

内容的提问来源于stack exchange,提问作者John Doe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 05:50:22