如何将混合元素类型的列表转换为整数列表并构建银行危机面板数据?
解决混合类型危机年份的面板数据生成问题
首先,我们得先把你提取的data_banking列表里的混合类型元素统一转换成整数年份的列表——这是解决问题的核心。搞定这一步后,生成面板数据的虚拟变量就顺理成章了。
步骤1:处理混合类型的危机年份数据
写一个专门的函数来解析每个元素,覆盖你遇到的三种情况:单个整数年份、逗号分隔的多年份字符串、NaN:
import pandas as pd import numpy as np def parse_crisis_years(item): # 处理空值(NaN)的情况 if pd.isna(item): return [] # 处理单个整数年份的情况 elif isinstance(item, int): return [item] # 处理多个年份的字符串情况 elif isinstance(item, str): # 按逗号分割,去掉每个年份前后的空格,转成整数,过滤掉无效空值 year_strings = [s.strip() for s in item.split(",")] return [int(year) for year in year_strings if year.isdigit()] # 其他意外类型直接返回空列表 else: return [] # 处理你的data_banking列表 processed_banking = [parse_crisis_years(item) for item in data_banking]
这个函数会把每个元素转换成干净的整数年份列表,比如:
- 输入
1994→ 输出[1994] - 输入
'1980, 1989, 1995, 2001'→ 输出[1980, 1989, 1995, 2001] - 输入
nan→ 输出[]
步骤2:生成面板数据的虚拟变量
现在可以基于处理好的年份列表,高效生成banking_crisis列表,同时构建countries_long和years_long:
# 定义年份范围 years = list(range(1970, 2020)) countries_long = [] years_long = [] banking_crisis = [] # 遍历每个国家对应的处理后的年份列表 for country, crisis_years in zip(countries, processed_banking): # 为当前国家生成50年的重复值 country_repeats = [country] * len(years) countries_long.extend(country_repeats) years_long.extend(years) # 对每一年判断是否在危机年份里,生成0/1标记 for year in years: banking_crisis.append(1 if year in crisis_years else 0) # 构建最终的DataFrame banking = pd.DataFrame({ 'Country': countries_long, 'Year': years_long, 'Banking_Crisis': banking_crisis })
这样处理后,不管是单次危机还是多次危机的国家,都能正确生成虚拟变量了。
额外优化:用pandas原生方法更高效
如果你的原始DataFramedata还在,其实可以不用手动构建列表,直接用pandas的向量化操作来实现,代码更简洁且性能更好:
# 先给原始DataFrame添加处理后的年份列表列 data['Banking_Crisis_Years'] = data['Systemic Banking Crisis (starting date)'].apply(parse_crisis_years) # 生成包含所有国家-年份组合的面板框架 all_country_years = pd.MultiIndex.from_product( [data['Country'], years], names=['Country', 'Year'] ).to_frame(index=False) # 把危机年份拆分成每行一个年份,标记为1 crisis_markers = data.explode('Banking_Crisis_Years').rename( columns={'Banking_Crisis_Years': 'Year'} ).assign(Banking_Crisis=1)[['Country', 'Year', 'Banking_Crisis']] # 合并面板框架和危机标记,空值填充为0 banking = all_country_years.merge( crisis_markers, on=['Country', 'Year'], how='left' ).fillna(0).astype({'Banking_Crisis': int})
这种方法避免了手动嵌套循环,尤其是数据量较大时,效率提升会很明显。
内容的提问来源于stack exchange,提问作者Signe Holst Madsen
相关产品推荐
相关产品推荐

