如何正确读取Pickle保存的DataFrame二进制文件并解决下标访问报错问题
如何正确读取Pickle保存的DataFrame二进制文件并解决下标访问报错问题
嘿,我一眼就看出你问题出在哪了——你直接对着文件对象用下标取列,这肯定不行呀!咱们先理清楚错误原因,再一步步改好代码:
错误根源
你在main函数里打开文件后,直接写了X = f[col_names[:-1]],但这里的f是_io.BufferedRandom类型的文件流对象,它根本不是你之前保存的Pandas DataFrame!只有把Pickle文件里的内容反序列化加载成真正的DataFrame对象后,才能用下标去选列。
修正后的完整代码
你的create_dataset函数是没问题的,问题全在读取部分。我给你改好两种可行的读取方式:
方式1:用pickle模块反序列化(和你保存的方式对应)
import pandas as pd import pickle as pkl def create_dataset(path): """ creates an binary file with dataset saved in it. """ df = pd.read_csv(path) saved_path = "some_path" with open(saved_path,'wb+') as f: pkl.dump(df,f) return saved_path, df.columns.tolist() def main(): bin_path, col_names = create_dataset(dataset_loc) print(col_names) # 关键修正:先把Pickle里的DataFrame加载到内存 with open(bin_path, 'rb') as f: # 读取用'rb'就够了,不需要'rb+' loaded_df = pkl.load(f) # 这一步得到的才是你要的DataFrame # 现在可以正常操作列了 X = loaded_df[col_names[:-1]] y = loaded_df[col_names[-1]] # 后续可以用X、y做训练/分析啦 print(X.head()) print(y.head())
方式2:用Pandas自带的pd.read_pickle()(更简洁)
Pandas专门给DataFrame做了Pickle读写的封装,不用手动处理文件打开关闭,代码更清爽:
import pandas as pd def create_dataset(path): df = pd.read_csv(path) saved_path = "some_path" # 其实保存也可以用pd.to_pickle,更简洁 df.to_pickle(saved_path) return saved_path, df.columns.tolist() def main(): bin_path, col_names = create_dataset(dataset_loc) print(col_names) # 一行就读取到DataFrame loaded_df = pd.read_pickle(bin_path) X = loaded_df[col_names[:-1]] y = loaded_df[col_names[-1]]
几个小提醒
- 记得提前导入需要的库:
import pandas as pd,如果用pickle模块的话还要import pickle as pkl - 读取文件时用
'rb'模式就足够,'rb+'是读写模式,你只是读取数据的话完全没必要用 - 保存和读取的方式要对应:用
pkl.dump保存就用pkl.load读,用df.to_pickle保存就用pd.read_pickle读,当然交叉用也能行,但同系列的方式更稳妥
核心总结一下:文件流对象不是DataFrame,必须先把Pickle里序列化的DataFrame反序列化加载到内存,得到真正的DataFrame实例后,才能进行列选择、数据筛选这些操作~




