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

基于Hungarian_rate划分区间,实现各区间人口总和均衡的Python方案

按人口总和均衡划分Hungarian_rate区间的解决方案

要实现基于Hungarian_rate划分区间且每组人口总和尽可能均衡,不能直接用pd.qcut(仅按样本数量均分),需先按Hungarian_rate排序,再通过动态规划找到最优分组(最小化各组人口与目标值的误差),具体步骤如下:

步骤1:数据预处理与目标计算

先按Hungarian_rate从小到大排序(区间需保持rate的连续性),再计算总人口和每组目标人口:

import pandas as pd

data = {
    "Town": ["F", "A", "N", "O", "B", "L", "C", "K", "J", "E", "G", "M", "I", "D", "H"],
    "Hungarian_rate": [1, 4, 5, 8, 9, 10, 15, 15, 20, 22, 23, 31, 41, 60, 75],
    "Population": [40, 10, 30, 50, 30, 20, 40, 30, 20, 20, 20, 10, 40, 50, 30]
}
df = pd.DataFrame(data)

# 按Hungarian_rate排序,保证区间连续性
df_sorted = df.sort_values('Hungarian_rate').reset_index(drop=True)
# 计算总人口与每组目标人口(440/5=88)
total_pop = df_sorted['Population'].sum()
target_per_group = total_pop / 5

步骤2:动态规划寻找最优分组

通过动态规划计算前i个城镇分成k组的最小误差,回溯得到分组边界:

# 计算人口前缀和,快速获取任意区间的人口总和
prefix_pop = df_sorted['Population'].cumsum().tolist()
prefix_pop.insert(0, 0)  # prefix_pop[0]=0,prefix_pop[i]代表前i个城镇的人口总和
n = len(df_sorted)
k_groups = 5

# 初始化DP数组:dp[i][j] = 前i个城镇分成j组的最小平方误差和
INF = float('inf')
dp = [[INF] * (k_groups + 1) for _ in range(n + 1)]
dp[0][0] = 0
# 记录分割点,用于回溯分组
split_points = [[0] * (k_groups + 1) for _ in range(n + 1)]

# 填充DP数组
for i in range(1, n + 1):
    for j in range(1, min(k_groups, i) + 1):
        # 遍历所有可能的前一组分割点
        for m in range(j - 1, i):
            current_sum = prefix_pop[i] - prefix_pop[m]
            # 计算当前组与目标值的平方误差
            error = (current_sum - target_per_group) ** 2
            if dp[m][j - 1] + error < dp[i][j]:
                dp[i][j] = dp[m][j - 1] + error
                split_points[i][j] = m

# 回溯获取分组索引
groups = []
current_idx = n
for j in range(k_groups, 0, -1):
    prev_idx = split_points[current_idx][j]
    groups.append(list(range(prev_idx, current_idx)))
    current_idx = prev_idx
groups.reverse()

步骤3:标记分组与验证结果

为数据添加分组标签,并验证每组人口总和:

# 为每个城镇分配带区间的分组标签
for idx, group in enumerate(groups, 1):
    min_rate = df_sorted.loc[group[0], 'Hungarian_rate']
    max_rate = df_sorted.loc[group[-1], 'Hungarian_rate']
    df_sorted.loc[group, 'Population_Group'] = f"Group {idx} ({min_rate}-{max_rate})"

# 查看每组人口总和
group_pop_summary = df_sorted.groupby('Population_Group')['Population'].sum().reset_index()
print(group_pop_summary)

最终分组结果

运行后得到的分组及人口总和如下(每组均接近目标值88):

Population_GroupPopulation
Group 1 (1-5)80
Group 2 (8-10)100
Group 3 (15-20)90
Group 4 (22-41)90
Group 5 (60-75)80

各组人口总和方差极小,既满足人口均衡需求,又保持了Hungarian_rate区间的连续性。

内容的提问来源于stack exchange,提问作者Kristián Ővári

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 14:19:52