এখনই আমি CSV
স্ক্রিপ্টটি চালানোর সময় একটি ডেটা ফ্রেম হিসাবে মোটামুটি বড় আমদানি করছি সেই ডেটাফ্রেমকে রানের মাঝে ক্রমাগত উপলব্ধ রাখার জন্য কি কোনও ভাল সমাধান আছে যাতে আমাকে স্ক্রিপ্টটি চালানোর জন্য অপেক্ষা করে সমস্ত সময় ব্যয় করতে হবে না?
এখনই আমি CSV
স্ক্রিপ্টটি চালানোর সময় একটি ডেটা ফ্রেম হিসাবে মোটামুটি বড় আমদানি করছি সেই ডেটাফ্রেমকে রানের মাঝে ক্রমাগত উপলব্ধ রাখার জন্য কি কোনও ভাল সমাধান আছে যাতে আমাকে স্ক্রিপ্টটি চালানোর জন্য অপেক্ষা করে সমস্ত সময় ব্যয় করতে হবে না?
উত্তর:
সবচেয়ে সহজ উপায় এটি ব্যবহার করে আচার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
যথাযথভাবে অবচিত হয়)।
আর একটি জনপ্রিয় পছন্দ হ'ল এইচডিএফ 5 ( পাইটবেবলস ) ব্যবহার করা যা বড় ডেটাসেটগুলির জন্য খুব দ্রুত অ্যাক্সেসের সময় দেয়:
store = HDFStore('store.h5')
store['df'] = df # save it
store['df'] # load it
আরও উন্নত কৌশলগুলি কুকবুকে আলোচনা করা হয়েছে ।
০.০৩ যেহেতু এছাড়াও রয়েছে ইজ প্যাক যা আন্তঃব্যবহারের জন্য জেএসএনের দ্রুত বিকল্প হিসাবে বা আপনার কাছে পাইথন অবজেক্ট / পাঠ্য-ভারী ডেটা ( এই প্রশ্নটি দেখুন ) ভাল হতে পারে।
যদিও ইতিমধ্যে কিছু উত্তর রয়েছে তবে আমি একটি দুর্দান্ত তুলনা পেয়েছি যার মধ্যে তারা পান্ডাস ডেটা ফ্রেমগুলি সিরিয়ালায়িত করার বিভিন্ন উপায় চেষ্টা করেছে: দক্ষতার সাথে পান্ডাস ডেটা ফ্রেমগুলি সঞ্চয় করুন ।
তারা তুলনা:
তাদের পরীক্ষায়, তারা দুটি কলাম পৃথকভাবে পরীক্ষা করে 1000,000 সারি একটি ডেটা ফ্রেম সিরিয়ালিকৃত: একটি পাঠ্য ডেটা সহ, অন্যটি সংখ্যা সহ। তাদের দাবি অস্বীকারকারী বলেছেন:
আপনার বিশ্বাস করা উচিত নয় যা অনুসরণ করে আপনার ডেটাতে সাধারণীকরণ করে। আপনার নিজের ডেটা দেখতে হবে এবং নিজেই মানদণ্ড চালানো উচিত
তারা যা পরীক্ষার জন্য উত্স কোড তা অনলাইনে উপলব্ধ । যেহেতু এই কোডটি সরাসরি কাজ করে না আমি কিছু ছোটখাটো পরিবর্তন করেছি, যা আপনি এখানে পেতে পারেন: সিরিয়ালাইজ.পেই আমি নিম্নলিখিত ফলাফল পেয়েছি:
তারা আরও উল্লেখ করেছেন যে টেক্সট ডেটাগুলিকে শ্রেণিবদ্ধ ডেটাতে রূপান্তর করার সাথে সাথে সিরিয়ালকরণ আরও দ্রুত হয় ization তাদের পরীক্ষায় প্রায় 10 বার দ্রুত (পরীক্ষার কোডটিও দেখুন)
সম্পাদনা : সিএসভির চেয়ে আচারের জন্য উচ্চতর সময়গুলি ব্যবহৃত ডেটা ফর্ম্যাট দ্বারা ব্যাখ্যা করা যেতে পারে। ডিফল্টরূপে pickle
একটি মুদ্রণযোগ্য ASCII উপস্থাপনা ব্যবহার করে, যা বৃহত্তর ডেটা সেট উত্পন্ন করে। গ্রাফ থেকে যেমন দেখা যায়, নতুন বাইনারি ডেটা ফর্ম্যাট (সংস্করণ 2, pickle-p2
) ব্যবহার করে আচারের লোডের সময় অনেক কম।
আরও কিছু উল্লেখ:
numpy.fromfile
দ্রুততম।.to_pickle()
(যা বাইনারি স্টোরেজ ব্যবহার করে) এর বিপরীতে .to_hdf()
(সংক্ষেপণ ছাড়াই) The লক্ষ্যটি ছিল গতি, এইচডিএফের জন্য ফাইলের আকার ছিল 11x পিকল এবং লোড করার সময় 5x পিকল ছিল আমার তথ্যটি ছিল প্রতিটি each 7k সারি x 6 টি
যদি আমি সঠিকভাবে বুঝতে পারি pandas.read_csv()
তবে আপনি ইতিমধ্যে ব্যবহার করছেন তবে বিকাশ প্রক্রিয়াটি গতি বাড়িয়ে তুলতে চান যাতে প্রতিবার আপনি স্ক্রিপ্ট সম্পাদনা করার সময় আপনাকে ফাইলটি লোড করতে না হয়, তা কি ঠিক? আমার কয়েকটি সুপারিশ রয়েছে:
আপনি pandas.read_csv(..., nrows=1000)
যখন বিকাশ করছেন তখন কেবলমাত্র টেবিলের উপরের বিটটি লোড করতে সিএসভি ফাইলের কেবলমাত্র অংশে লোড করতে পারেন
ব্যবহার ipython একটি ইন্টারেক্টিভ সেশনের জন্য, এই ধরনের যে আপনি হিসাবে আপনি সম্পাদন করা মেমরি পান্ডাস টেবিল রাখা এবং আপনার স্ক্রিপ্টটি পুনরায় লোড করুন।
CSV কে এইচডিএফ 5 টেবিলে রূপান্তর করুন
আর-সামঞ্জস্যপূর্ণ পালকের বাইনারি ফর্ম্যাটে আপডেট হওয়া ব্যবহার DataFrame.to_feather()
এবং pd.read_feather()
ডেটা সংরক্ষণ করার জন্য যা সুপার দ্রুত (আমার হাতে, সংখ্যার ডেটার তুলনায় কিছুটা দ্রুত এবং স্ট্রিং ডেটাতে আরও দ্রুত)।pandas.to_pickle()
আপনি এই উত্তরটি স্ট্যাকওভারফ্লোতেও আগ্রহী হতে পারেন ।
to_feather
স্ট্রিং ডেটাতে কেন ভাল কাজ করবে? আমি বেঞ্চমার্ক করেছি to_pickle
এবং to_feature
আমার সংখ্যার ডেটাফ্রেমে এবং আচার প্রায় 3x দ্রুত।
আচার ভাল কাজ করে!
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
সিএসভি ফাইল নয়, সম্ভবত @ অ্যান্ডি হেইডেন্স উত্তরে প্রস্তাবিত হিসাবে এক্সটেনশনটি ব্যবহার করা আরও ভাল ।
আপনি পালক বিন্যাস ফাইল ব্যবহার করতে পারেন। এটি অত্যন্ত দ্রুত।
df.to_feather('filename.ft')
R
ব্যবহার করে ব্যবহার করা যেতে পারে feather
।
পান্ডাস ডেটা ফ্রেমের 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 , এসকিউএল ) রয়েছে। তবে, pickle
প্রথম শ্রেণির নাগরিক নয় (আপনার সেটআপের উপর নির্ভর করে), কারণ:
pickle
সম্ভাব্য সুরক্ষা ঝুঁকি। ফরম জরান জন্য পাইথন ডকুমেন্টেশন :সতর্কবাণী
pickle
মডিউল ভ্রান্ত বা বিদ্বেষপূর্ণভাবে নির্মাণ তথ্য ব্যাপারে নিশ্চিন্ত নয়। অবিশ্বস্ত বা অ-প্রত্যক্ষ উত্স থেকে কখনই পাতলা ডেটা পাওয়া যায় না।
আপনার সেটআপ / ব্যবহারের উপর নির্ভর করে উভয় সীমাবদ্ধতা প্রযোজ্য নয়, তবে আমি pickle
প্যান্ডাস ডেটা ফ্রেমের জন্য ডিফল্ট অধ্যবসায় হিসাবে সুপারিশ করব না ।
আমি নপি ফাইলগুলি ব্যবহার করতে পছন্দ করি কারণ সেগুলি দ্রুত এবং সহজেই কাজ করা যায়। 1 মিলিয়ন পয়েন্টের 1 টি কলাম সহ একটি ডেটা ফ্রেম সংরক্ষণ এবং লোড করার জন্য এখানে একটি সাধারণ বেঞ্চমার্ক।
import numpy as np
import pandas as pd
num_dict = {'voltage': np.random.rand(1000000)}
num_df = pd.DataFrame(num_dict)
আইপথনের %%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
খারাপ না!
পাইথন 2 ব্যবহার করে নম্পটি ফাইলটি সংরক্ষণ করে এবং তারপরে পাইথন 3 (বা বিপরীতে) ব্যবহার করে খোলার চেষ্টা করা আছে সেখানে একটি সমস্যা আছে।
https://docs.python.org/3/library/pickle.html
আচার প্রোটোকল ফর্ম্যাটগুলি:
প্রোটোকল সংস্করণ 0 মূল "মানব-পঠনযোগ্য" প্রোটোকল এবং পাইথনের পূর্ববর্তী সংস্করণগুলির সাথে পিছনে সামঞ্জস্যপূর্ণ।
প্রোটোকল সংস্করণ 1 একটি পুরানো বাইনারি ফর্ম্যাট যা পাইথনের পূর্ববর্তী সংস্করণগুলির সাথেও সামঞ্জস্যপূর্ণ।
প্রোটোকল সংস্করণ 2 পাইথন ২.৩ এ চালু হয়েছিল। এটি নতুন স্টাইলের ক্লাসগুলির অনেক বেশি কার্যকর পিকিং সরবরাহ করে। প্রোটোকল 2 দ্বারা আনা উন্নতি সম্পর্কে তথ্যের জন্য পিইপি 307 দেখুন।
প্রোটোকল সংস্করণ 3 পাইথন 3.0 এ যুক্ত করা হয়েছিল। এটিতে বাইটস অবজেক্টের জন্য সুস্পষ্ট সমর্থন রয়েছে এবং পাইথন ২.x দ্বারা এটি পিক করা যায় না। এটি ডিফল্ট প্রোটোকল এবং যখন অন্য পাইথন 3 সংস্করণের সাথে সামঞ্জস্যতা প্রয়োজন তখন প্রস্তাবিত প্রোটোকল।
প্রোটোকল সংস্করণ 4 পাইথন ৩.৪ এ যুক্ত করা হয়েছিল। এটি অনেক বড় অবজেক্টের জন্য বিভিন্ন ধরণের অবজেক্ট এবং কয়েকটি ডেটা ফর্ম্যাট অপ্টিমাইজেশনের জন্য সমর্থন যোগ করে। প্রোটোকল 4 দ্বারা আনা উন্নতি সম্পর্কে তথ্যের জন্য পিইপি 3154 দেখুন।
সামগ্রিক পদক্ষেপটি প্যারাও / পালক (প্যান্ডাস / ইজেক্টপ্যাক থেকে অবজ্ঞা সতর্কতা) করা হয়েছে। তবে আমি pyarrow সঙ্গে একটি চ্যালেঞ্জ আছে অস্থায়ী নির্দেশের মধ্যে ডেটার সাথে pyarrow 0.15.1 0.16.0 সঙ্গে deserialized করা যাবে না ধারাবাহিকভাবে দেখুন 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>
=+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+=
পালক এবং parquet আমার ডেটা ফ্রেমের জন্য কাজ করে না। আমি পেয়ারো ব্যবহার চালিয়ে যাচ্ছি। তবে আমি আচার দিয়ে পরিপূরক করব (কোনও সংক্ষেপণ নেই)। ক্যাশে স্টোর যখন পাইয়ারো এবং আচার সিরিয়ালাইজড ফর্ম। ক্যাশে ফ্যালব্যাক থেকে আচারে পড়ার সময় যদি পেয়ারো ডিসরিয়ালাইজেশন ব্যর্থ হয়।
ফর্ম্যাটটি আপনার ব্যবহারের ক্ষেত্রে নির্ভর করে
পান্ডাস ফাইল ফর্ম্যাটগুলির তুলনা এই ভিডিওতে রয়েছে ।