274 lines
11 KiB
Python
274 lines
11 KiB
Python
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键继续...") |