This commit is contained in:
2025-09-11 21:42:06 +08:00
parent ec35818b13
commit cbabf9c956

View File

@@ -0,0 +1,274 @@
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键继续...")