পান্ডাস ব্যবহার করে ডেটাফ্রেম কীভাবে সংরক্ষণ করবেন


317

এখনই আমি CSVস্ক্রিপ্টটি চালানোর সময় একটি ডেটা ফ্রেম হিসাবে মোটামুটি বড় আমদানি করছি সেই ডেটাফ্রেমকে রানের মাঝে ক্রমাগত উপলব্ধ রাখার জন্য কি কোনও ভাল সমাধান আছে যাতে আমাকে স্ক্রিপ্টটি চালানোর জন্য অপেক্ষা করে সমস্ত সময় ব্যয় করতে হবে না?


2
হ্যাঁ, পাইথন ব্যবহার করে এটি আমার অন্যতম প্রধান অভিযোগ - ডেটা ফ্রেমগুলি সংরক্ষণ এবং পুনরুদ্ধারের সহজ উপায় নেই। আর এবং এসএএস এই ক্ষেত্রে আরও বেশি ব্যবহারকারীবান্ধব।
রবার্টএফ

উত্তর:


481

সবচেয়ে সহজ উপায় এটি ব্যবহার করে আচার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

আরও উন্নত কৌশলগুলি কুকবুকে আলোচনা করা হয়েছে ।


০.০৩ যেহেতু এছাড়াও রয়েছে ইজ প্যাক যা আন্তঃব্যবহারের জন্য জেএসএনের দ্রুত বিকল্প হিসাবে বা আপনার কাছে পাইথন অবজেক্ট / পাঠ্য-ভারী ডেটা ( এই প্রশ্নটি দেখুন ) ভাল হতে পারে।


8
@ জিেকাজয়েড সেভ টু_পিকলে অবচয় করা হয়েছে (যা সিএসভির পরিবর্তে একটি আচার তৈরি করে, যা অনেক দ্রুত / ভিন্ন বস্তু)।
অ্যান্ডি হেডেন

9
@ জিেকাজয়েড ক্ষেত্রে লোড হওয়ার পরে ডেটা রূপান্তর করা দরকার (অর্থাত্ স্ট্রিং / অবজেক্ট ডেটটাইম 64৪) এটি সংরক্ষণ করা সিএসভি লোড করার পরে আবার করা দরকার, ফলস্বরূপ কর্মক্ষমতা হ্রাস পায়। আচার তার বর্তমান অবস্থায় ডেটাফ্রেম সংরক্ষণ করে এভাবে ডেটা এবং এর ফর্ম্যাটটি সংরক্ষণ করা হয়। এটি ব্যাপক কর্মক্ষমতা বৃদ্ধি করতে পারে।
harbun

4
আচার এবং এইচডিএফএস স্টোর উভয়ই 8 জিবি-র বেশি ডেটাফ্রেম সংরক্ষণ করতে পারে না। বিকল্প আছে?
ব্যবহারকারী 1700890

1
@ ব্যবহারকারী 1700890 এলোমেলো ডেটা (পাঠ্য এবং অ্যারে) থেকে উত্পন্ন করার চেষ্টা করুন এবং একটি নতুন প্রশ্ন পোস্ট করুন। আমি মনে করি না যে এটি সঠিক / সন্দেহজনক হতে পারে আমরা কিছু অনুপস্থিত। নতুন প্রশ্নটি আরও চোখ পাবে, তবে পুনরুত্পাদনকারী একটি ডেটা ফ্রেম অন্তর্ভুক্ত / জেনারেট করার চেষ্টা করুন :)
অ্যান্ডি হেডেন

1
@YixingLiu আপনি আসলে পরে মোড পরিবর্তন করতে পারেন stackoverflow.com/a/16249655/1240268
অ্যান্ডি হেডেন

100

যদিও ইতিমধ্যে কিছু উত্তর রয়েছে তবে আমি একটি দুর্দান্ত তুলনা পেয়েছি যার মধ্যে তারা পান্ডাস ডেটা ফ্রেমগুলি সিরিয়ালায়িত করার বিভিন্ন উপায় চেষ্টা করেছে: দক্ষতার সাথে পান্ডাস ডেটা ফ্রেমগুলি সঞ্চয় করুন

তারা তুলনা:

  • আচার: আসল ASCII ডেটা ফর্ম্যাট
  • সিপিকেল, একটি সি লাইব্রেরি
  • পিকেল-পি 2: আরও নতুন বাইনারি ফর্ম্যাট ব্যবহার করে
  • জেসন: স্ট্যান্ডার্ডলিব জসন লাইব্রেরি
  • json-no-index: json এর মত, তবে ইনডেক্স ছাড়াও
  • msgpack: বাইনারি JSON বিকল্প
  • CSV তে
  • এইচডিএফস্টোর: এইচডিএফ 5 স্টোরেজ ফর্ম্যাট

তাদের পরীক্ষায়, তারা দুটি কলাম পৃথকভাবে পরীক্ষা করে 1000,000 সারি একটি ডেটা ফ্রেম সিরিয়ালিকৃত: একটি পাঠ্য ডেটা সহ, অন্যটি সংখ্যা সহ। তাদের দাবি অস্বীকারকারী বলেছেন:

আপনার বিশ্বাস করা উচিত নয় যা অনুসরণ করে আপনার ডেটাতে সাধারণীকরণ করে। আপনার নিজের ডেটা দেখতে হবে এবং নিজেই মানদণ্ড চালানো উচিত

তারা যা পরীক্ষার জন্য উত্স কোড তা অনলাইনে উপলব্ধ । যেহেতু এই কোডটি সরাসরি কাজ করে না আমি কিছু ছোটখাটো পরিবর্তন করেছি, যা আপনি এখানে পেতে পারেন: সিরিয়ালাইজ.পেই আমি নিম্নলিখিত ফলাফল পেয়েছি:

সময় তুলনা ফলাফল

তারা আরও উল্লেখ করেছেন যে টেক্সট ডেটাগুলিকে শ্রেণিবদ্ধ ডেটাতে রূপান্তর করার সাথে সাথে সিরিয়ালকরণ আরও দ্রুত হয় ization তাদের পরীক্ষায় প্রায় 10 বার দ্রুত (পরীক্ষার কোডটিও দেখুন)

সম্পাদনা : সিএসভির চেয়ে আচারের জন্য উচ্চতর সময়গুলি ব্যবহৃত ডেটা ফর্ম্যাট দ্বারা ব্যাখ্যা করা যেতে পারে। ডিফল্টরূপে pickleএকটি মুদ্রণযোগ্য ASCII উপস্থাপনা ব্যবহার করে, যা বৃহত্তর ডেটা সেট উত্পন্ন করে। গ্রাফ থেকে যেমন দেখা যায়, নতুন বাইনারি ডেটা ফর্ম্যাট (সংস্করণ 2, pickle-p2) ব্যবহার করে আচারের লোডের সময় অনেক কম।

আরও কিছু উল্লেখ:


1
আপনার প্রশ্নটি ব্যাখ্যা করতে আমি আমার উত্তর আপডেট করেছি। সংক্ষিপ্তসার হিসাবে: ডিফল্টরূপে আচার একটি ASCII ফর্ম্যাটে ডেটা সঞ্চয় করে।
14:48 এ পঠিত

1
আহ, সেই ব্যাখ্যার জন্য থেক্স! একটি দ্রষ্টব্য হিসাবে, পান্ডাস ডেটা ফ্রেম। টো-পিকেল পিকেএল ব্যবহার করছে বলে মনে হচ্ছে H HIGHEST_PROTOCOL (2 হওয়া উচিত)
এনটিজি

2
মনে হচ্ছে উপরের লিঙ্কযুক্ত ব্লগটি ( দক্ষতার সাথে স্টোর পান্ডাস ডেটা ফ্রেমগুলি মুছে ফেলা হয়েছে। আমি আমার নিজস্ব তুলনা করেছি .to_pickle()(যা বাইনারি স্টোরেজ ব্যবহার করে) এর বিপরীতে .to_hdf()(সংক্ষেপণ ছাড়াই) The লক্ষ্যটি ছিল গতি, এইচডিএফের জন্য ফাইলের আকার ছিল 11x পিকল এবং লোড করার সময় 5x পিকল ছিল আমার তথ্যটি ছিল প্রতিটি each 7k সারি x 6 টি
কলসের

1
পৃষ্ঠাটি এখনও বিদ্যমান, আপনাকে কেবল অনুসরণকারী স্ল্যাশ সরিয়ে ফেলতে হবে: দক্ষতার সাথে পান্ডাস ডেটা ফ্রেমগুলি সঞ্চয় করুন
আইয়ানএসআর

2
@ মাইক উইলিয়ামসন, আমার পরীক্ষায়, এইচডিএফের তুলনায় আচার 5x দ্রুত ছিল এবং ডিস্কের স্থানটিও 1/11 নিয়েছিল (যেমন এইচডিএফ ডিস্কের চেয়ে 11x বড় এবং আচারের মতো ডিস্ক থেকে লোড করতে 5x সময় নিয়েছিল) took পান্ডাস 0.22.0 সহ পাইথন 3 এ সমস্ত ছিল।
hamx0r

35

যদি আমি সঠিকভাবে বুঝতে পারি pandas.read_csv()তবে আপনি ইতিমধ্যে ব্যবহার করছেন তবে বিকাশ প্রক্রিয়াটি গতি বাড়িয়ে তুলতে চান যাতে প্রতিবার আপনি স্ক্রিপ্ট সম্পাদনা করার সময় আপনাকে ফাইলটি লোড করতে না হয়, তা কি ঠিক? আমার কয়েকটি সুপারিশ রয়েছে:

  1. আপনি pandas.read_csv(..., nrows=1000)যখন বিকাশ করছেন তখন কেবলমাত্র টেবিলের উপরের বিটটি লোড করতে সিএসভি ফাইলের কেবলমাত্র অংশে লোড করতে পারেন

  2. ব্যবহার ipython একটি ইন্টারেক্টিভ সেশনের জন্য, এই ধরনের যে আপনি হিসাবে আপনি সম্পাদন করা মেমরি পান্ডাস টেবিল রাখা এবং আপনার স্ক্রিপ্টটি পুনরায় লোড করুন।

  3. CSV কে এইচডিএফ 5 টেবিলে রূপান্তর করুন

  4. আর-সামঞ্জস্যপূর্ণ পালকের বাইনারি ফর্ম্যাটে আপডেট হওয়া ব্যবহার DataFrame.to_feather()এবং pd.read_feather()ডেটা সংরক্ষণ করার জন্য যা সুপার দ্রুত (আমার হাতে, সংখ্যার ডেটার তুলনায় কিছুটা দ্রুত এবং স্ট্রিং ডেটাতে আরও দ্রুত)।pandas.to_pickle()

আপনি এই উত্তরটি স্ট্যাকওভারফ্লোতেও আগ্রহী হতে পারেন ।


আপনি কি জানেন to_featherস্ট্রিং ডেটাতে কেন ভাল কাজ করবে? আমি বেঞ্চমার্ক করেছি to_pickleএবং to_featureআমার সংখ্যার ডেটাফ্রেমে এবং আচার প্রায় 3x দ্রুত।
zyxue

@ অজিক্স ভাল প্রশ্ন, আমি সততার সাথে পালকের জিনিসগুলির সাথে খুব বেশি খেলিনি, সুতরাং আমার কোনও উত্তর নেই
নোহ

20

আচার ভাল কাজ করে!

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

8
নোট করুন যে উত্পন্ন ফাইলগুলি .pklসিএসভি ফাইল নয়, সম্ভবত @ অ্যান্ডি হেইডেন্স উত্তরে প্রস্তাবিত হিসাবে এক্সটেনশনটি ব্যবহার করা আরও ভাল ।
8:48 এ চালিত

5

আপনি পালক বিন্যাস ফাইল ব্যবহার করতে পারেন। এটি অত্যন্ত দ্রুত।

df.to_feather('filename.ft')

এবং তথ্যগুলি সরাসরি লাইব্রেরি Rব্যবহার করে ব্যবহার করা যেতে পারে feather
জেমস হিরশর্ন

4

পান্ডাস ডেটা ফ্রেমের 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

4

ইতিমধ্যে উল্লিখিত হিসাবে একটি ডেটা ফ্রেম সংরক্ষণ করার জন্য বিভিন্ন বিকল্প এবং ফাইল ফর্ম্যাট ( HDF5 , JSON , CSV , parquet , এসকিউএল ) রয়েছে। তবে, pickleপ্রথম শ্রেণির নাগরিক নয় (আপনার সেটআপের উপর নির্ভর করে), কারণ:

  1. pickleসম্ভাব্য সুরক্ষা ঝুঁকি। ফরম জরান জন্য পাইথন ডকুমেন্টেশন :

সতর্কবাণীpickle মডিউল ভ্রান্ত বা বিদ্বেষপূর্ণভাবে নির্মাণ তথ্য ব্যাপারে নিশ্চিন্ত নয়। অবিশ্বস্ত বা অ-প্রত্যক্ষ উত্স থেকে কখনই পাতলা ডেটা পাওয়া যায় না।

  1. pickleধীর. এই এখানে এবং এখানে benchmarks।

আপনার সেটআপ / ব্যবহারের উপর নির্ভর করে উভয় সীমাবদ্ধতা প্রযোজ্য নয়, তবে আমি pickleপ্যান্ডাস ডেটা ফ্রেমের জন্য ডিফল্ট অধ্যবসায় হিসাবে সুপারিশ করব না ।


1

অমিত ফাইলের ফর্ম্যাটগুলি সংখ্যা সংক্রান্ত ডেটার জন্য বেশ দ্রুত

আমি নপি ফাইলগুলি ব্যবহার করতে পছন্দ করি কারণ সেগুলি দ্রুত এবং সহজেই কাজ করা যায়। 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

খারাপ না!

CONS

পাইথন 2 ব্যবহার করে নম্পটি ফাইলটি সংরক্ষণ করে এবং তারপরে পাইথন 3 (বা বিপরীতে) ব্যবহার করে খোলার চেষ্টা করা আছে সেখানে একটি সমস্যা আছে।


6
নোট করুন যে এই সমাধানটি আপনার সমস্ত কলামের নাম মুছে ফেলবে এবং আপনার পূর্ণসংখ্যার ডেটাগুলি ভাসতে বদলে দেবে :(
জোসেফ গারভিন

0

https://docs.python.org/3/library/pickle.html

আচার প্রোটোকল ফর্ম্যাটগুলি:

প্রোটোকল সংস্করণ 0 মূল "মানব-পঠনযোগ্য" প্রোটোকল এবং পাইথনের পূর্ববর্তী সংস্করণগুলির সাথে পিছনে সামঞ্জস্যপূর্ণ।

প্রোটোকল সংস্করণ 1 একটি পুরানো বাইনারি ফর্ম্যাট যা পাইথনের পূর্ববর্তী সংস্করণগুলির সাথেও সামঞ্জস্যপূর্ণ।

প্রোটোকল সংস্করণ 2 পাইথন ২.৩ এ চালু হয়েছিল। এটি নতুন স্টাইলের ক্লাসগুলির অনেক বেশি কার্যকর পিকিং সরবরাহ করে। প্রোটোকল 2 দ্বারা আনা উন্নতি সম্পর্কে তথ্যের জন্য পিইপি 307 দেখুন।

প্রোটোকল সংস্করণ 3 পাইথন 3.0 এ যুক্ত করা হয়েছিল। এটিতে বাইটস অবজেক্টের জন্য সুস্পষ্ট সমর্থন রয়েছে এবং পাইথন ২.x দ্বারা এটি পিক করা যায় না। এটি ডিফল্ট প্রোটোকল এবং যখন অন্য পাইথন 3 সংস্করণের সাথে সামঞ্জস্যতা প্রয়োজন তখন প্রস্তাবিত প্রোটোকল।

প্রোটোকল সংস্করণ 4 পাইথন ৩.৪ এ যুক্ত করা হয়েছিল। এটি অনেক বড় অবজেক্টের জন্য বিভিন্ন ধরণের অবজেক্ট এবং কয়েকটি ডেটা ফর্ম্যাট অপ্টিমাইজেশনের জন্য সমর্থন যোগ করে। প্রোটোকল 4 দ্বারা আনা উন্নতি সম্পর্কে তথ্যের জন্য পিইপি 3154 দেখুন।


0

সংস্করণ জুড়ে পাইয়ারো সামঞ্জস্য

সামগ্রিক পদক্ষেপটি প্যারাও / পালক (প্যান্ডাস / ইজেক্টপ্যাক থেকে অবজ্ঞা সতর্কতা) করা হয়েছে। তবে আমি 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 আমার ডেটা ফ্রেমের জন্য কাজ করে না। আমি পেয়ারো ব্যবহার চালিয়ে যাচ্ছি। তবে আমি আচার দিয়ে পরিপূরক করব (কোনও সংক্ষেপণ নেই)। ক্যাশে স্টোর যখন পাইয়ারো এবং আচার সিরিয়ালাইজড ফর্ম। ক্যাশে ফ্যালব্যাক থেকে আচারে পড়ার সময় যদি পেয়ারো ডিসরিয়ালাইজেশন ব্যর্থ হয়।


এটি প্রশ্নের উত্তর দেয় না
জেসন এস

0

ফর্ম্যাটটি আপনার ব্যবহারের ক্ষেত্রে নির্ভর করে

  • নোটবুক সেশনগুলির মধ্যে ডেটা ফ্রেম সংরক্ষণ করুন - পালক , যদি আপনি আচার ব্যবহার করেন - ঠিক আছে।
  • সম্ভাব্যতম ফাইল আকারে ডেটা ফ্রেম সংরক্ষণ করুন - parquet বা pickle.gz (আপনার ডেটার জন্য আরও ভাল কি তা পরীক্ষা করুন)
  • একটি খুব বড় ডেটা ফ্রেম (10+ মিলিয়ন সারি) সংরক্ষণ করুন - এইচডিএফ
  • - অন্য প্ল্যাটফর্ম (না পাইথন) যে অন্যান্য ফরম্যাটের সমর্থন করে না ডেটা পড়তে পারবে CSV , csv.gz যদি, চেক Parquet সমর্থিত
  • আপনার চোখ দিয়ে / এক্সেল / গুগল শিটস / গিট ডিফ - সিএসভি ব্যবহার করে পর্যালোচনা করতে সক্ষম হন
  • একটি DataFrame যে প্রায় সব র্যাম লাগে সংরক্ষণ করুন - CSV

পান্ডাস ফাইল ফর্ম্যাটগুলির তুলনা এই ভিডিওতে রয়েছে

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.