Python 如何在磁盘上可逆地存储和加载数据帧
现在,每次运行脚本时,我都会导入一个相当大的Python 如何在磁盘上可逆地存储和加载数据帧,python,pandas,dataframe,Python,Pandas,Dataframe,现在,每次运行脚本时,我都会导入一个相当大的CSV作为数据帧。有没有一个好的解决方案可以让数据帧在两次运行之间始终可用,这样我就不必花那么多时间等待脚本运行?最简单的方法是使用: 然后,您可以使用以下方法将其加载回: df = pd.read_pickle(file_name) 注意:在0.11.1之前,save和load是实现这一点的唯一方法(它们现在被弃用,分别支持to_pickle和read_pickle) 另一个流行的选择是使用()来提供对大型数据集的访问时间: import pan
CSV
作为数据帧。有没有一个好的解决方案可以让数据帧在两次运行之间始终可用,这样我就不必花那么多时间等待脚本运行?最简单的方法是使用:
然后,您可以使用以下方法将其加载回:
df = pd.read_pickle(file_name)
注意:在0.11.1之前,save
和load
是实现这一点的唯一方法(它们现在被弃用,分别支持to_pickle
和read_pickle
)
另一个流行的选择是使用()来提供对大型数据集的访问时间:
import pandas as pd
store = pd.HDFStore('store.h5')
store['df'] = df # save it
store['df'] # load it
更多高级策略将在中讨论
从0.13开始,作为JSON的更快替代方案,或者如果您有python对象/文本重数据(请参阅),还有哪些可能更好地实现互操作性。如果我理解正确,您已经在使用
pandas.read\u csv()
但是希望加快开发过程,这样您就不必在每次编辑脚本时都加载文件,对吗?我有几点建议:
pandas.read_CSV(…,nrows=1000)
仅加载CSV文件的一部分,以便在进行开发时仅加载表的顶部位DataFrame.to_feather()
和pd.read_feather()
以超级快速的R兼容二进制格式存储数据(在我手中,在数字数据上比pandas.to_pickle()
稍快,在字符串数据上则快得多)import pandas as pd
df.to_pickle('123.pkl') #to save the dataframe, df to 123.pkl
df1 = pd.read_pickle('123.pkl') #to load 123.pkl back to the dataframe df
虽然已经有了一些答案,但我发现了一个很好的比较,他们尝试了几种序列化数据帧的方法: 他们比较:
- pickle:原始ASCII数据格式
- cPickle,一个C库
- pickle-p2:使用较新的二进制格式
- json:standardlibjson库
- json无索引:与json类似,但没有索引
- msgpack:二进制JSON替代方案
- CSV
- hdfstore:HDF5存储格式
pickle-p2
)的pickle具有更低的加载时间
其他一些参考资料:
- 在这个问题中有一个非常详细的例子,它比较了不同的库来读取csv文件和一个基准。结果是,读取csv文件的速度最快
- 另一个 显示和cPickle是序列化中最快的
to_pickle
功能:
import pandas as pd
a = pd.DataFrame({'A':[0,1,0,1,0],'B':[True, True, False, False, False]})
print a
# A B
# 0 0 True
# 1 1 True
# 2 0 False
# 3 1 False
# 4 0 False
a.to_pickle('my_file.pkl')
b = pd.read_pickle('my_file.pkl')
print b
# A B
# 0 0 True
# 1 1 True
# 2 0 False
# 3 1 False
# 4 0 False
Numpy文件格式对于数字数据来说非常快
我更喜欢使用numpy文件,因为它们快速且易于使用。
这里有一个简单的基准测试,用于保存和加载一个数据帧,其中1列包含100万个点
import numpy as np
import pandas as pd
num_dict = {'voltage': np.random.rand(1000000)}
num_df = pd.DataFrame(num_dict)
使用ipython的%%timeit
魔术功能
%%timeit
with open('num.npy', 'wb') as np_file:
np.save(np_file, num_df)
输出是
100 loops, best of 3: 5.97 ms per loop
将数据加载回数据帧
%%timeit
with open('num.npy', 'rb') as np_file:
data = np.load(np_file)
data_df = pd.DataFrame(data)
输出是
100 loops, best of 3: 5.12 ms per loop
不错
欺骗
如果使用python 2保存numpy文件,然后尝试使用python 3打开(反之亦然),则会出现问题。可以使用feather格式的文件。速度非常快
df.to_feather('filename.ft')
如前所述,有不同的选项和文件格式(,)来存储数据帧。但是,
pickle
不是一等公民(取决于您的设置),因为:
pickle
是一种潜在的安全风险。表格:pickle
速度很慢。查找和测试基准pickle
作为熊猫数据帧的默认持久性
pickle协议格式:
协议版本0是原始的“人类可读”协议,与早期版本的Python向后兼容
协议版本1是一种旧的二进制格式,它也与Python的早期版本兼容
Python2.3中引入了协议版本2。它提供了对新样式类更有效的酸洗。参考PEP 307,了解协议2带来的改进信息
Python 3.0中添加了协议版本3。它明确支持字节对象,并且不能被Python2.x取消勾选。这是默认协议,是需要与其他Python 3版本兼容时的推荐协议
Python 3.4中添加了协议版本4。它增加了对非常大的对象的支持,对更多种类的对象进行酸洗,并对一些数据进行处理
df.to_feather('filename.ft')
import sys, pickle, zlib, warnings, io
class foocls:
def pyarrow(out): return pa.serialize(out).to_buffer().to_pybytes()
def msgpack(out): return out.to_msgpack()
def pickle(out): return pickle.dumps(out)
def feather(out): return out.to_feather(io.BytesIO())
def parquet(out): return out.to_parquet(io.BytesIO())
warnings.filterwarnings("ignore")
for c in foocls.__dict__.values():
sbreak = True
try:
c(out)
print(c.__name__, "before serialization", sys.getsizeof(out))
print(c.__name__, sys.getsizeof(c(out)))
%timeit -n 50 c(out)
print(c.__name__, "zlib", sys.getsizeof(zlib.compress(c(out))))
%timeit -n 50 zlib.compress(c(out))
except TypeError as e:
if "not callable" in str(e): sbreak = False
else: raise
except (ValueError) as e: print(c.__name__, "ERROR", e)
finally:
if sbreak: print("=+=" * 30)
warnings.filterwarnings("default")
pyarrow before serialization 533366
pyarrow 120805
1.03 ms ± 43.9 µs per loop (mean ± std. dev. of 7 runs, 50 loops each)
pyarrow zlib 20517
2.78 ms ± 81.8 µs per loop (mean ± std. dev. of 7 runs, 50 loops each)
=+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+=
msgpack before serialization 533366
msgpack 109039
1.74 ms ± 72.8 µs per loop (mean ± std. dev. of 7 runs, 50 loops each)
msgpack zlib 16639
3.05 ms ± 71.7 µs per loop (mean ± std. dev. of 7 runs, 50 loops each)
=+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+=
pickle before serialization 533366
pickle 142121
733 µs ± 38.3 µs per loop (mean ± std. dev. of 7 runs, 50 loops each)
pickle zlib 29477
3.81 ms ± 60.4 µs per loop (mean ± std. dev. of 7 runs, 50 loops each)
=+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+=
feather ERROR feather does not support serializing a non-default index for the index; you can .reset_index() to make the index into column(s)
=+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+=
parquet ERROR Nested column branch had multiple children: struct<x: double, y: double>
=+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+=