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

如何用Python计算各地理区域通勤距离的均值与中位数?

普查通勤数据的均值与中位数计算问题

我是Python数据分析新手,正在处理普查通勤数据。示例数据如下:

geo_areaTotal2-5km5-10km
E020000015378385241
E020000023238474394
E020000035238603541
E020000043113354277
E020000054862684532
E020000064271676408

其中第一列为地理区域,第二列为总通勤人数,其余列为对应距离区间(2-5km、5-10km等)的通勤人数频次(实际数据超7000行,省略了其他距离区间列)。我需要计算每个地理区域的通勤距离均值和中位数。

我自行编写了以下中位数计算函数,但不确定是否正确:

def median_calculator(df):
    full_list_of_numbers = []
    for col in df.columns:
        full_list_of_numbers.append(((df[col].cumsum() - (df[col].sum(axis=0)/2).T) < 0).sum())
    return full_list_of_numbers

目前我卡在均值计算上,同时想咨询是否可以通过df.groupby('geographical_areas').agg({mean_distance: 'mean', 'median_distance':'median'})来实现需求?


均值计算方法

计算通勤距离均值的核心是给每个距离区间设定区间中点,再通过加权平均计算:

  1. 先为所有距离区间定义中点值(比如2-5km取3.5km,5-10km取7.5km)
  2. 对每个地理区域,用「区间中点 × 该区间通勤人数」的总和,除以总通勤人数,得到均值

示例代码:

import pandas as pd

# 读取数据(示例)
df = pd.DataFrame([
    ["E02000001", 5378, 385, 241],
    ["E02000002", 3238, 474, 394],
    ["E02000003", 5238, 603, 541],
    ["E02000004", 3113, 354, 277],
    ["E02000005", 4862, 684, 532],
    ["E02000006", 4271, 676, 408]
], columns=["geo_area", "Total", "2-5km", "5-10km"])

# 定义所有区间的中点映射
distance_midpoints = {
    "2-5km": 3.5,
    "5-10km": 7.5
    # 补充其他距离区间的中点值
}

# 计算每个区域的加权均值
df["mean_distance"] = df.apply(
    lambda row: sum(row[col] * distance_midpoints[col] for col in distance_midpoints) / row["Total"],
    axis=1
)

中位数函数的问题

你当前的中位数函数逻辑存在错误:

  • 函数遍历的是列,但实际需要按**行(单个地理区域)**计算中位数
  • 逻辑未结合区间的距离信息,仅对列累计值做判断,无法得到实际通勤距离的中位数

正确的中位数计算逻辑:

  1. 按距离从小到大遍历区间,构建每个区域的累计人数分布
  2. 找到累计人数超过总人数一半的第一个区间,通过线性插值计算精确中位数

示例代码:

def calculate_median(row, interval_order, interval_midpoints):
    total = row["Total"]
    cumulative = 0
    prev_interval = None
    # 按距离从小到大遍历区间
    for interval in interval_order:
        count = row[interval]
        cumulative += count
        # 找到中位数所在区间
        if cumulative >= total / 2:
            prev_cumulative = cumulative - count
            # 线性插值计算精确中位数
            lower_bound = interval_midpoints[prev_interval] if prev_interval else 0
            median = lower_bound + (total/2 - prev_cumulative)/count * (interval_midpoints[interval] - lower_bound)
            return median
        prev_interval = interval
    return 0

# 定义区间的从小到大顺序
interval_order = ["2-5km", "5-10km"]  # 补充其他区间
# 区间中点映射(与均值计算一致)
interval_midpoints = {"2-5km":3.5, "5-10km":7.5}

# 计算每个区域的中位数
df["median_distance"] = df.apply(lambda row: calculate_median(row, interval_order, interval_midpoints), axis=1)

关于groupby的疑问

你提到的groupby写法无法直接实现需求:

  • 你的数据每行对应一个地理区域,不需要分组聚合(groupby用于对多行同组数据聚合,这里每个组就是单行)
  • mean_distance和median_distance是需要计算的衍生列,不是原始数据列,无法直接在agg中调用

正确做法是先按上述方法计算出mean_distance和median_distance列,若后续需要按其他维度分组,再使用groupby。


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

相关产品推荐
方舟 Agent Plan

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

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