답변:
가장 쉬운 방법은 다음을 사용하여 피클 하는 것입니다 to_pickle
.
df.to_pickle(file_name) # where to save it, usually as a .pkl
그런 다음 다음을 사용하여 다시로드 할 수 있습니다.
df = pd.read_pickle(file_name)
참고 : 0.11.1 이전 save
과 load
이 작업을 수행 할 수있는 유일한 방법 (그들은 지금의 찬성되지 않습니다했다 to_pickle
및 read_pickle
각각).
또 다른 대중적인 선택은 대용량 데이터 세트에 매우 빠른 액세스 시간을 제공 하는 HDF5 ( pytables ) 를 사용 하는 것입니다 .
store = HDFStore('store.h5')
store['df'] = df # save it
store['df'] # load it
더 고급 전략은 요리 책 에서 논의됩니다 .
0.13부터는 JSON보다 빠른 대안으로 또는 파이썬 객체 / 텍스트가 많은 데이터가있는 경우 상호 운용성을 위해 더 나은 msgpack 이 있습니다 ( 이 질문 참조 ).
이미 몇 가지 답변이 있지만 Pandas DataFrames를 효율적 으로 직렬화하는 여러 가지 방법을 시도한 훌륭한 비교를 발견했습니다. 효율적으로 Pandas DataFrames 저장하십시오 .
그들은 다음을 비교합니다.
실험에서 그들은 개별적으로 테스트 된 두 개의 열 (하나는 텍스트 데이터, 다른 하나는 숫자)로 1,000,000 행의 DataFrame을 직렬화합니다. 그들의 면책 조항은 다음과 같이 말합니다.
다음 내용이 데이터를 일반화한다고 믿지 않아야합니다. 자신의 데이터를보고 벤치 마크를 직접 실행해야합니다.
그들이 참조하는 테스트의 소스 코드는 온라인에서 볼 수 있습니다 . 이 코드가 직접 작동하지 않았기 때문에 약간의 변경 사항을 만들었습니다. serialize.py 다음과 같은 결과를 얻었습니다.
또한 텍스트 데이터를 범주 형 데이터로 변환 하면 직렬화가 훨씬 빠릅니다. 테스트에서 약 10 배 정도 빠릅니다 (테스트 코드 참조).
편집 : CSV보다 피클에 더 많은 시간을 사용 된 데이터 형식으로 설명 할 수 있습니다. 기본적으로 pickle
더 큰 데이터 세트를 생성하는 인쇄 가능한 ASCII 표현을 사용합니다. 그러나 그래프에서 볼 수 있듯이 최신 이진 데이터 형식 (버전 2, pickle-p2
)을 사용하는 피클 은로드 시간이 훨씬 짧습니다.
다른 참고 문헌들 :
numpy.fromfile
것이 가장 빠릅니다..to_pickle()
)와 바이너리 바이너리를 사용하는 자체 비교를 .to_hdf()
했습니다. 목표는 속도, HDF의 파일 크기는 11x Pickle,로드하는 시간이었습니다 5x Pickle. 내 데이터는 ~ 7k 행 x 6 열의 ~ 5k 파일 (주로 숫자)
내가 올바르게 이해하고 있다면 이미 사용하고 pandas.read_csv()
있지만 스크립트를 편집 할 때마다 파일을로드 할 필요가 없도록 개발 프로세스를 가속화하고 싶습니다. 맞습니까? 몇 가지 권장 사항이 있습니다.
pandas.read_csv(..., nrows=1000)
개발하는 동안 테이블의 최상위 비트 만로드하는 데 사용하여 CSV 파일의 일부만로드 할 수 있습니다.
스크립트를 편집하고 다시로드 할 때 팬더 테이블을 메모리에 유지하도록 대화식 세션에 ipython 을 사용 하십시오.
CSV를 HDF5 테이블 로 변환
업데이트 된 사용 DataFrame.to_feather()
및 pd.read_feather()
데이터를 R- 호환 페더 이진 형식으로 초고속으로 저장합니다 (제 손에는 pandas.to_pickle()
숫자 데이터 보다 약간 빠르며 문자열 데이터에서는 훨씬 빠릅니다).
to_feather
문자열 데이터에서 잘 작동 하는지 알고 있습니까? 나는 벤치 마크 to_pickle
하고 to_feature
숫자 데이터 프레임과 피클이 약 3 배 빠릅니다.
피클은 잘 작동합니다!
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
.pkl
로 @Andy Haydens 답변에 제안 된 확장명을 사용하는 것이 좋습니다.
페더 형식 파일을 사용할 수 있습니다. 매우 빠릅니다.
df.to_feather('filename.ft')
R
사용하여 데이터를 직접 사용할 수 feather
있습니다.
Pandas DataFrame에는 DataFrame 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
이미 언급했듯이 데이터 프레임을 저장하기위한 다양한 옵션 및 파일 형식 ( HDF5 , JSON , CSV , parquet , SQL )이 있습니다. 그러나 다음과 같은 pickle
이유로 일급 시민이 아닙니다 (설정에 따라 다름).
pickle
잠재적 인 보안 위험입니다. pickle에 대한 Python 문서를 작성하십시오 .경고
pickle
모듈은 잘못된 또는 악의적으로 제작 된 데이터에 대한 보안 상 안전하지 않을 수 있습니다. 신뢰할 수 없거나 인증되지 않은 소스에서받은 데이터를 피클 링하지 마십시오.
설정 / 사용법에 따라 두 제한 사항이 모두 적용되지는 않지만 pickle
팬더 데이터 프레임의 기본 지속성으로 권장하지 않습니다 .
numpy 파일은 빠르고 작업하기 쉽기 때문에 numpy 파일을 사용하는 것을 선호합니다. 다음은 1 열 1 백만 포인트의 데이터 프레임을 저장하고로드하기위한 간단한 벤치 마크입니다.
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을 사용하여 열거 나 그 반대의 경우 문제가 있습니다.
https://docs.python.org/3/library/pickle.html
피클 프로토콜 형식 :
프로토콜 버전 0은 원래 "사람이 읽을 수있는"프로토콜이며 이전 버전의 Python과 호환됩니다.
프로토콜 버전 1은 이전 이진 형식이며 이전 버전의 Python 과도 호환됩니다.
프로토콜 버전 2는 Python 2.3에서 도입되었습니다. 새로운 스타일의 클래스를 훨씬 더 효율적으로 산 세척합니다. 프로토콜 2의 개선 사항에 대한 정보는 PEP 307을 참조하십시오.
프로토콜 버전 3은 Python 3.0에 추가되었습니다. 바이트 객체를 명시 적으로 지원하며 Python 2.x에서 피클 링 할 수 없습니다. 이것은 기본 프로토콜이며 다른 Python 3 버전과의 호환성이 필요한 경우 권장되는 프로토콜입니다.
프로토콜 버전 4는 Python 3.4에서 추가되었습니다. 매우 큰 객체, 더 많은 종류의 객체 및 일부 데이터 형식 최적화를 지원합니다. 프로토콜 4의 개선 사항에 대한 정보는 PEP 3154를 참조하십시오.
전반적인 이동은 pyarrow / feather (pandas / msgpack의 지원 중단 경고)입니다. 그러나 사양에 일시적인 pyarrow가있는 문제가 있습니다. pyarrow 0.15.1로 직렬화 된 데이터는 0.16.0 ARROW-7961 으로 직렬화 해제 할 수 없습니다 . redis를 사용하기 위해 직렬화를 사용하고 있으므로 바이너리 인코딩을 사용해야합니다.
다양한 옵션을 다시 테스트했습니다 (주피터 노트북 사용)
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")
내 데이터 프레임에 대한 다음 결과 ( out
주피터 변수)
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>
=+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+=
깃털과 쪽모이 세공이 내 데이터 프레임에서 작동하지 않습니다. 나는 pyarrow를 계속 사용할 것입니다. 그러나 나는 피클 (압축 없음)을 보충 할 것입니다. 저장소 파이로 및 피클 직렬화 된 양식을 캐시하기 위해 쓸 때. pyarrow deserialisation이 실패하면 캐시 폴백에서 피클로 읽을 때.
형식은 사용 사례에 따라 다릅니다.
팬더 파일 형식의 비교는 이 비디오에 있습니다.