如何去除Pandas中query提取数据时附带的索引信息?
问题与解决方案
问题描述
首次在Stack Overflow提问,现有代码中df_history是包含多变量的DataFrame,想要提取其中的close变量并按currency类别排序,但用.query提取数据时,得到的对象附带原索引编号(如BTC对象中的179、178等),希望去除这些索引;另外尝试用ast处理数据但效果不佳。
原代码:
additional_rows = [] for currency in selected_coins: df_history = df_history.sort_values(['date'], ascending=True) row_data = [currency, df_history.query('granularity == \'daily\' and currency == @currency')['close'], df_history.query('granularity == \'daily\' and currency == @currency').head(180)['close'].pct_change(), df_history['date'] ] additional_rows.append(row_data) df_additional_info = pd.DataFrame(additional_rows, columns = ['currency', 'close', 'returns', 'df_history']) df_additional_info.set_index('currency').transpose()
尝试的无效处理代码:
import ast list_of_lists = df_additional_info.close.to_list() flat_list = [i for sublist in list_of_lists for i in ast.literal_eval(sublist)] uniq_list = list(set(flat_list)) len(uniq_list),len(flat_list)
解决方案
1. 核心解决思路:提取数据时直接转成列表去除索引
.query返回的是Series对象,自带原DataFrame的索引,只需用.tolist()或.values.tolist()把Series转成纯数值列表,就能彻底去掉索引。
2. 优化后的完整代码
# 先整体排序一次,避免循环内重复排序浪费性能 df_history_sorted = df_history.sort_values(['date'], ascending=True) additional_rows = [] for currency in selected_coins: # 一次性筛选当前币种的日线close数据,减少重复查询 daily_close = df_history_sorted.query('granularity == "daily" and currency == @currency')['close'] # 转成列表去除索引 close_list = daily_close.tolist() # 计算180天收益率,转成列表并处理首值NaN(这里用fillna(0)填充,可按需调整) returns_list = daily_close.head(180).pct_change().fillna(0).tolist() # 对应筛选当前币种的日期,避免取整个DataFrame的日期 date_list = df_history_sorted.query('granularity == "daily" and currency == @currency')['date'].tolist() row_data = [currency, close_list, returns_list, date_list] additional_rows.append(row_data) # 构造新DataFrame df_additional_info = pd.DataFrame(additional_rows, columns=['currency', 'close', 'returns', 'dates']) # 转置后得到的结果就不会带原索引了 final_result = df_additional_info.set_index('currency').transpose()
3. 为什么之前的ast处理无效?
df_additional_info.close中的元素是Series对象,不是字符串格式的列表,所以ast.literal_eval无法解析,直接用.tolist()转成列表才是正确的处理方式。
内容的提问来源于stack exchange,提问作者Steve Jobs
相关产品推荐
相关产品推荐

