如何在循环中为从Quandl获取的DataFrame按国家命名?
解决DataFrame动态命名与数据下载的问题
我看了你的代码,发现几个关键问题导致你没法实现“data_国家名”的DataFrame命名,同时数据下载逻辑也存在漏洞,下面一步步帮你解决:
核心问题分析
- Ticker匹配逻辑错误:你用
any(e.lower() == 'germany' for e in exchanges)的方式设置ticker,这会导致只要输入列表里有一个匹配的国家,所有循环里的下载都会复用同一个ticker,而非每个国家对应自己的专属代码。 - 未初始化存储容器:直接用
data[i]但没先把data定义为字典,会触发NameError。 - Global变量滥用:不需要用
global传递DataFrame,用字典存储或合理动态创建变量更符合Python的编码习惯。
优化后的解决方案
方案1:用字典存储(推荐,更易维护)
字典是处理“国家-对应DataFrame”这类键值对场景的最佳选择,比零散变量更清晰,后续批量操作也更方便:
import quandl from quandl.errors.quandl_error import NotFoundError from datetime import date, timedelta import matplotlib.pyplot as plt import pandas as pd from scipy import interpolate import numpy as np from scipy.optimize import leastsq # 建立国家与Quandl代码的映射字典,替代冗长的elif判断 COUNTRY_TICKER_MAP = { '德国': 'CHRIS/EUREX_FDAX1', '法国': 'CHRIS/LIFFE_FCE1', '美国': 'MULTPL/SP500_REAL_PRICE_MONTH', '中国香港': 'CHRIS/HKEX_HSI1', '印度': 'NSE/CNX_NIFTY', '英国': 'CHRIS/LIFFE_Z1', '日本': 'NIKKEI/ALL_STOCK', '中国': 'WFE/INDEXES_SHANGHAISESSECOMPOSITEINDEX' } ALLOWED_COUNTRIES = list(COUNTRY_TICKER_MAP.keys()) def MainFormula(): exchanges = [] # 循环获取5个有效国家输入 while len(exchanges) < 5: country = input(f'请从{ALLOWED_COUNTRIES}中选择第{len(exchanges)+1}个国家:') if country in ALLOWED_COUNTRIES: exchanges.append(country) else: print(f'输入无效,请从指定列表中选择国家!') # 初始化存储所有DataFrame的字典 country_data = {} # 计算日期范围 today = date.today() ten_years_ago = today - timedelta(days=365*10) start_date = ten_years_ago.strftime("%Y-%m-%d") end_date = today.strftime("%Y-%m-%d") for country in exchanges: try: ticker = COUNTRY_TICKER_MAP[country] # 下载数据并存入字典,键为"data_国家名" data_key = f'data_{country}' country_data[data_key] = quandl.get(ticker, start_date=start_date, end_date=end_date) print(f'已成功下载{country}的股指数据,存储键为:{data_key}') except NotFoundError: print(f'无法找到{country}的对应股指数据,请检查国家名称或Quandl代码!') except Exception as e: print(f'下载{country}数据时出错:{str(e)}') # 如需单独提取某个国家的数据,比如中国: # china_data = country_data['data_中国'] return country_data # 运行程序 program_result = MainFormula() print('所有数据已存储在返回的字典中')
方案2:动态创建全局变量(不推荐,不易维护)
如果你一定要创建data_中国、data_美国这类独立变量,可以用globals()函数实现,但这种方式会让变量零散分布,后续排查问题或批量操作都很麻烦:
在循环里替换为以下代码即可:
for country in exchanges: try: ticker = COUNTRY_TICKER_MAP[country] df = quandl.get(ticker, start_date=start_date, end_date=end_date) # 动态创建全局变量 var_name = f'data_{country}' globals()[var_name] = df print(f'已创建变量{var_name}存储{country}数据') except NotFoundError: print(f'无法找到{country}的对应股指数据!')
额外优化点
- 用映射字典替代冗长的elif判断,代码可读性和扩展性大幅提升。
- 增加输入有效性检查,避免用户输入无效国家导致后续报错。
- 完善异常处理逻辑,不仅捕获NotFoundError,还处理其他可能的异常并给出明确提示。
- 日期格式改用
%Y-%m-%d,更符合Quandl API的推荐格式,避免格式兼容问题。
内容的提问来源于stack exchange,提问作者Alberto Alvarez
相关产品推荐
相关产品推荐

