Files
YunNanProject/Test/population_statistics.py
2025-09-11 21:42:06 +08:00

274 lines
11 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import json
import os
from datetime import datetime
class PopulationStatistics:
def __init__(self, data_file):
"""初始化人口统计类,加载数据文件"""
self.data_file = data_file
self.data = self.load_data()
self.years = list(range(2015, 2025)) # 2015-2024年
def load_data(self):
"""加载人口数据JSON文件"""
try:
with open(self.data_file, 'r', encoding='utf-8') as f:
return json.load(f)
except FileNotFoundError:
print(f"错误:找不到数据文件 {self.data_file}")
return []
except json.JSONDecodeError:
print(f"错误:数据文件 {self.data_file} 格式不正确")
return []
def get_province_data(self):
"""获取云南省全省数据"""
for item in self.data:
if item['area_name'] == '云南省' and item['area_code'] == '530000000':
return item
return None
def get_city_data(self, city_name):
"""获取指定城市的数据"""
for item in self.data:
if item['area_name'] == city_name:
return item
return None
def get_all_cities(self):
"""获取所有地市级城市列表"""
cities = []
# 地市级城市的area_code格式为53XX00000
for item in self.data:
if len(item['area_code']) == 9 and item['area_code'][-5:] == '00000' and item['area_code'] != '530000000':
cities.append(item)
return cities
def calculate_total_population_by_year(self, level='province'):
"""按年份计算总人口
level: 'province'(全省), 'city'(昆明市), 'all_cities'(所有地级市)
"""
result = {}
if level == 'province':
province_data = self.get_province_data()
if province_data:
result = province_data['total_population']
elif level == 'city':
city_data = self.get_city_data('昆明市')
if city_data:
result = city_data['total_population']
elif level == 'all_cities':
cities = self.get_all_cities()
for year in self.years:
total = 0
for city in cities:
if str(year) in city['total_population']:
total += city['total_population'][str(year)]
result[str(year)] = total
return result
def calculate_urbanization_trend(self, area_name='云南省'):
"""计算指定地区的城镇化率趋势"""
area_data = None
if area_name == '云南省':
area_data = self.get_province_data()
else:
area_data = self.get_city_data(area_name)
if area_data and 'urbanization_rate' in area_data:
return area_data['urbanization_rate']
return {}
def compare_city_populations(self, year=2023):
"""比较指定年份各城市的人口数量"""
cities = self.get_all_cities()
result = {}
for city in cities:
if str(year) in city['total_population']:
result[city['area_name']] = city['total_population'][str(year)]
# 按人口数量排序
return dict(sorted(result.items(), key=lambda x: x[1], reverse=True))
def calculate_population_growth(self, area_name='云南省', start_year=2020, end_year=2023):
"""计算指定地区在指定时间段内的人口增长率"""
area_data = None
if area_name == '云南省':
area_data = self.get_province_data()
else:
area_data = self.get_city_data(area_name)
if not area_data:
return None
start_pop = area_data['total_population'].get(str(start_year), 0)
end_pop = area_data['total_population'].get(str(end_year), 0)
if start_pop == 0:
return None
growth_rate = ((end_pop - start_pop) / start_pop) * 100
return growth_rate
def analyze_birth_rate(self, area_name='云南省'):
"""分析指定地区的出生率趋势"""
area_data = None
if area_name == '云南省':
area_data = self.get_province_data()
else:
area_data = self.get_city_data(area_name)
if not area_data or 'birth_population' not in area_data or 'total_population' not in area_data:
return {}
birth_rates = {}
for year in self.years:
year_str = str(year)
if year_str in area_data['birth_population'] and year_str in area_data['total_population']:
birth_pop = area_data['birth_population'][year_str]
total_pop = area_data['total_population'][year_str]
# 注意:总人口单位是万人,出生人口单位是个,需要统一单位
if total_pop > 0 and birth_pop > 0:
birth_rate = (birth_pop / (total_pop * 10000)) * 1000 # 千分比
birth_rates[year] = birth_rate
return birth_rates
def save_results_to_file(self, results, filename):
"""将统计结果保存到文件"""
# 创建结果目录
result_dir = os.path.join(os.path.dirname(self.data_file), '../Results')
os.makedirs(result_dir, exist_ok=True)
# 生成带时间戳的文件名
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
full_filename = f"{filename}_{timestamp}.txt"
full_path = os.path.join(result_dir, full_filename)
# 保存结果
with open(full_path, 'w', encoding='utf-8') as f:
f.write(f"人口统计结果 - 生成时间:{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n")
for key, value in results.items():
if isinstance(value, dict):
f.write(f"{key}:\n")
for k, v in value.items():
f.write(f" {k}: {v}\n")
else:
f.write(f"{key}: {value}\n")
print(f"统计结果已保存至:{full_path}")
return full_path
# 主函数演示如何使用这个类
if __name__ == "__main__":
# 数据文件路径
data_file = os.path.join(os.path.dirname(__file__), '../Data/RenKou.json')
# 创建统计类实例
stats = PopulationStatistics(data_file)
# 检查数据是否成功加载
if not stats.data:
print("无法加载数据,程序退出。")
exit(1)
# 主菜单
print("云南省人口数据统计分析工具")
print("========================")
while True:
print("\n请选择要执行的统计分析:")
print("1. 查看云南省历年总人口统计")
print("2. 查看昆明市历年总人口统计")
print("3. 分析云南省城镇化率趋势")
print("4. 分析昆明市城镇化率趋势")
print("5. 比较2023年各城市人口数量")
print("6. 计算云南省2020-2023年人口增长率")
print("7. 分析云南省出生率趋势")
print("8. 分析昆明市出生率趋势")
print("9. 导出所有统计结果")
print("0. 退出程序")
choice = input("请输入您的选择0-9")
if choice == '0':
print("感谢使用,再见!")
break
elif choice == '1':
result = stats.calculate_total_population_by_year('province')
print("\n云南省历年总人口统计(单位:万人):")
for year, population in result.items():
print(f"{year}年: {population}")
elif choice == '2':
result = stats.calculate_total_population_by_year('city')
print("\n昆明市历年总人口统计(单位:万人):")
for year, population in result.items():
print(f"{year}年: {population}")
elif choice == '3':
result = stats.calculate_urbanization_trend('云南省')
print("\n云南省历年城镇化率(单位:%")
for year, rate in result.items():
print(f"{year}年: {rate}")
elif choice == '4':
result = stats.calculate_urbanization_trend('昆明市')
print("\n昆明市历年城镇化率(单位:%")
for year, rate in result.items():
print(f"{year}年: {rate}")
elif choice == '5':
result = stats.compare_city_populations(2023)
print("\n2023年各城市人口数量排名单位万人")
for i, (city, population) in enumerate(result.items(), 1):
print(f"{i}. {city}: {population}")
elif choice == '6':
rate = stats.calculate_population_growth('云南省', 2020, 2023)
if rate is not None:
print(f"\n云南省2020-2023年人口增长率: {rate:.2f}%")
else:
print("\n无法计算人口增长率")
elif choice == '7':
result = stats.analyze_birth_rate('云南省')
print("\n云南省历年出生率(单位:‰):")
for year, rate in result.items():
print(f"{year}年: {rate:.2f}")
elif choice == '8':
result = stats.analyze_birth_rate('昆明市')
print("\n昆明市历年出生率(单位:‰):")
for year, rate in result.items():
print(f"{year}年: {rate:.2f}")
elif choice == '9':
# 收集所有统计结果
all_results = {
"云南省历年总人口统计(万人)": stats.calculate_total_population_by_year('province'),
"昆明市历年总人口统计(万人)": stats.calculate_total_population_by_year('city'),
"云南省历年城镇化率(%": stats.calculate_urbanization_trend('云南省'),
"昆明市历年城镇化率(%": stats.calculate_urbanization_trend('昆明市'),
"2023年各城市人口数量排名万人": stats.compare_city_populations(2023),
"云南省2020-2023年人口增长率%": stats.calculate_population_growth('云南省', 2020, 2023),
"云南省历年出生率(‰)": stats.analyze_birth_rate('云南省'),
"昆明市历年出生率(‰)": stats.analyze_birth_rate('昆明市')
}
# 保存结果到文件
file_path = stats.save_results_to_file(all_results, "population_statistics")
print(f"\n所有统计结果已保存至文件:{file_path}")
else:
print("\n无效的选择,请重新输入。")
# 等待用户按Enter键继续
input("\n按Enter键继续...")