কোনও পান্ডার ডেটা ফ্রেমের কতটুকু মেমরির প্রয়োজন হবে তা অনুমান করবেন কীভাবে?


125

আমি ভাবছিলাম ... আমি যদি বলি, বলুন, একটি 400MB সিএসভি ফাইলকে একটি পান্ডাস ডেটা ফ্রেমে (রিড_সিএসভি বা পঠন-টেবিল ব্যবহার করে) ব্যবহার করা হয়, তাহলে এর কতটা স্মৃতি প্রয়োজন হবে তা অনুমান করার কোনও উপায় আছে কি? কেবল ডেটা ফ্রেম এবং মেমরির আরও ভাল অনুভূতি পাওয়ার চেষ্টা করছি ...


আপনি সর্বদা প্রক্রিয়াটি দেখতে পারেন এবং এটি কোনও একক ফাইলের জন্য মেমরির ব্যবহার। আপনি যদি লিনাক্স চালাচ্ছেন topতবে Shift + Mআমার মেমরির ব্যবহারটি বাছাই করার চেষ্টা করুন ।
JayQuerie.com

আমি মনে করি আমার এই উন্মুক্ত পান্ডাস ইস্যুর বিজ্ঞাপন দেওয়া উচিত ।
অ্যান্ডি হেডেন

3
আমার 4 মিলিয়ন সারি সহ একটি বিশাল ডেটাফ্রেম রয়েছে। আমি আবিষ্কার করেছি যে এটির খালি সাবসেটটি গণনা করতে কয়েক সেকেন্ড x=df.loc[[]]সময় নেয় 0.1(শূন্য সারিগুলি বের করতে) এবং ততোধিকভাবে, কয়েকশ মেগাবাইট মেমরি লাগে, ঠিক যেমনটি মূল ডেটাফ্রেমের নীচে কিছু অনুলিপি করার কারণে।
osa ই

উত্তর:


97

df.memory_usage() প্রতিটি কলাম কতটা দখল করে তা ফিরিয়ে দেবে:

>>> df.memory_usage()

Row_ID            20906600
Household_ID      20906600
Vehicle           20906600
Calendar_Year     20906600
Model_Year        20906600
...

সূচী অন্তর্ভুক্ত করতে, পাস করুন index=True

সুতরাং সামগ্রিক মেমরির খরচ পেতে:

>>> df.memory_usage(index=True).sum()
731731000

এছাড়াও, পাসিং deep=Trueআরও নিখুঁত মেমোরি ব্যবহারের প্রতিবেদন সক্ষম করে, যা এতে থাকা সামগ্রীর সম্পূর্ণ ব্যবহারের জন্য অ্যাকাউন্ট করে accounts

এটি কারণ মেমরির ব্যবহারে উপাদানগুলির দ্বারা গ্রাহিত মেমরি অন্তর্ভুক্ত হয় না যা অ্যারের উপাদান নয় deep=False( যদি ডিফল্ট কেস) থাকে।


1
সমস্ত কলামের মেমরির যোগফল কি মেমরির ব্যবহারের উপর প্রভাব ফেলে? আমি আরও ওভারহেড থাকতে পারে কল্পনা করতে পারেন।
অগ্নিনির্বাপক

14
আপনি সত্যিই এটিও চানdeep=True
smci

Df.memory_usage () এর যোগফল sys.getsizeof (df) এর সমান হয় না! অনেকগুলি ওভারহেড রয়েছে। Smci উল্লিখিত হিসাবে, আপনি প্রয়োজনdeep=True
ভবঘুরে

11
এফওয়াইআই, memory_usage()বাইটে মেমরির ব্যবহারটি ফেরত দেয় (যেমনটি আপনি আশা করবেন)।
এঙ্গেল

2
গভীরের সাথে / ছাড়াই কেন এত বড় পার্থক্য = সত্য?
Nguai আল

83

এখানে বিভিন্ন পদ্ধতির তুলনা sys.getsizeof(df)করা সহজ - সহজ।

এই উদাহরণস্বরূপ, df814 সারি, 11 কলাম (2 ইনটস, 9 টি অবজেক্ট) সহ একটি ডেটাফ্রেম - একটি 427kb শেফফাইল থেকে পড়া

sys.getsizeof (df প্রয়োগ)

>>> sys আমদানি করুন
>>> sys.getsizeof (df)
(বাইটে ফলাফল দেয়)
462456

df.memory_usage ()

>>> df.memory_usage ()
...
(প্রতিটি কলাম 8 বাইট / সারি তালিকাভুক্ত)

>>> df.memory_usage ()। যোগফল ()
71712
(মোটামুটি সারি * কলস * 8 বাইট)

>>> df.memory_usage (গভীর = সত্য)
(প্রতিটি কলামের সম্পূর্ণ স্মৃতি ব্যবহারের তালিকাবদ্ধ করে)

>>> df.memory_usage (গভীর = সত্য) .সুম ()
(বাইটে ফলাফল দেয়)
462432

df.info ()

স্ট্যাডআউটে ডেটাফ্রেম তথ্য মুদ্রণ করে। প্রযুক্তিগতভাবে এগুলি হ'ল কিবিবাইটস (কিবি), কিলোবাইট নয় - যেমনটি ডক্টস্ট্রিং বলেছে, "মেমোরির ব্যবহার মানব-পঠনযোগ্য ইউনিটগুলিতে (বেস -২ উপস্থাপনা) দেখানো হয়।" সুতরাং বাইট পেতে 1024 গুণবে, যেমন 451.6 কিবি = 462,438 বাইট।

>>> df.info ()
...
মেমরির ব্যবহার: 70.0+ কেবি

>>> df.info (মেমরি_উসেজ = 'গভীর')
...
মেমরির ব্যবহার: 451.6 কেবি

g উপরের কোডটি কোন বস্তু বা মডিউলটির উল্লেখ করেছে?
জোজো

@ জোজো ওয়াফস - একটি টাইপো স্থির ছিল
ব্রায়ান বার্নস

2
আমি ব্যবহার করি df.info(memory_usage="deep"), এটি "392.6 মেগাবাইট" ফেরত দেয় sys.getsizeof(df)এবং df.memory_usage(index=True, deep=True).sum()উভয়ই প্রায় "411718016" (~ 411MB) ফেরত দেয়। আপনি দয়া করে ব্যাখ্যা করতে পারেন যে 3 টি ফলাফল কেন সামঞ্জস্যপূর্ণ নয়? ধন্যবাদ
Catbuilts

2
@ ব্রায়ানবার্নস: এর df.memory_usage(deep=True).sum()সাথে প্রায় একইরকম ফেরত দেয় df.memory_usage(index=True, deep=True).sum()। আমার ক্ষেত্রে, না indexঅনেক স্মৃতি নিতে। যথেষ্ট উত্সাহের ব্যাপার হল, আমি পাওয়া 411718016/1024/1024 = 392.6, তাই df.info(memory_usage="deep")ব্যবহার করতে পারেন 2^10রূপান্তর করতে বাইট থেকে মেগাবাইট , যা আমার বিভ্রান্ত করে তোলে। যাইহোক আপনার সহায়তার জন্য ধন্যবাদ: ডি।
Catbuilts

1
@ গুগল বিল্টস আহ, এটি ব্যাখ্যা করে! df.infoমেগাবাইট (10 ^ 6) না করে মেগাবাইট (2 ^ 10) ফিরিয়ে দিচ্ছে - উত্তরটি সংশোধন করবে।
ব্রায়ান বার্নস

43

আমি ভেবেছিলাম আলোচনায় আরও কিছু ডেটা আনব।

আমি এই ইস্যুতে বেশ কয়েকটি পরীক্ষা চালিয়েছি।

পাইথন resourceপ্যাকেজটি ব্যবহার করে আমি আমার প্রক্রিয়াটির স্মৃতি ব্যবহার করেছি।

এবং একটি StringIOবাফারে সিএসভি লিখে আমি সহজেই এটির আকার বাইটে পরিমাপ করতে পারি।

আমি দুটি পরীক্ষা চালিয়েছি, প্রত্যেকে 10,000 লাইন এবং 1,000,000 লাইনের মধ্যে 20 টি আকারের বর্ধনশীল ডেটাফ্রেম তৈরি করে। দু'জনেরই 10 টি কলাম রয়েছে।

প্রথম পরীক্ষায় আমি কেবল আমার ডেটাসেটে ভাসমান ব্যবহার করি।

লাইনের সংখ্যার ফাংশন হিসাবে সিএসভি ফাইলের সাথে তুলনা করে এইভাবে স্মৃতি বাড়ল। (মেগাবাইটে আকার)

ফ্লোট এন্ট্রি সহ সারি সংখ্যার ফাংশন হিসাবে মেগাবাইটে মেমরি এবং সিএসভি আকার

দ্বিতীয় পরীক্ষায় আমার একই পদ্ধতি ছিল, তবে ডেটাসেটের ডেটাতে কেবল ছোট ছোট স্ট্রিং থাকে।

স্ট্রিং এন্ট্রি সহ সারি সংখ্যার ফাংশন হিসাবে মেগাবাইটে মেমরি এবং সিএসভি আকার

দেখে মনে হয় যে CSV এর আকার এবং ডেটাফ্রেমের আকারের সম্পর্কটি অনেকটা আলাদা হতে পারে তবে মেমরির আকারটি সর্বদা 2-3 এর একটি ফ্যাক্টর দ্বারা বড় হবে (এই পরীক্ষায় ফ্রেমের আকারের জন্য)

আমি আরও উত্তর দিয়ে এই উত্তরটি সম্পূর্ণ করতে চাই, আপনি যদি আমাকে বিশেষ কিছু চেষ্টা করতে চান তবে মন্তব্য করুন।


আপনার y অক্ষ কী?
ইলিয়া ভি। শুরভ

1
মেগাবাইটে ডিস্কে ম্যাক্স_আরএস এবং সিএসভি আকার
ফায়ারেলেক্স

31

আপনাকে বিপরীতে এটি করতে হবে।

In [4]: DataFrame(randn(1000000,20)).to_csv('test.csv')

In [5]: !ls -ltr test.csv
-rw-rw-r-- 1 users 399508276 Aug  6 16:55 test.csv

প্রযুক্তিগতভাবে মেমরি এটি সম্পর্কে (যা সূচকগুলি অন্তর্ভুক্ত করে)

In [16]: df.values.nbytes + df.index.nbytes + df.columns.nbytes
Out[16]: 168000160

সুতরাং একটি 400MB ফাইল সহ 168MB মেমরি, 20 ফ্ল্যাট কলামের 1 এম সারি

DataFrame(randn(1000000,20)).to_hdf('test.h5','df')

!ls -ltr test.h5
-rw-rw-r-- 1 users 168073944 Aug  6 16:57 test.h5

বাইনারি এইচডিএফ 5 ফাইল হিসাবে লেখার সময় আরও বেশি কমপ্যাক্ট করা উচিত

In [12]: DataFrame(randn(1000000,20)).to_hdf('test.h5','df',complevel=9,complib='blosc')

In [13]: !ls -ltr test.h5
-rw-rw-r-- 1 users 154727012 Aug  6 16:58 test.h5

ডেটা এলোমেলো ছিল, সুতরাং সংক্ষেপণ খুব বেশি সাহায্য করে না


খুব চালাক! আপনার মেমরিটি কীভাবে মাপবেন কোনও ফাইল ব্যবহার করে ফাইলটি পড়তে হবে read_csv?
অ্যান্ডি হেডেন

আপনি যেমন পড়েন তেমন পরিমাপ করার কোনও ধারণা নেই; আইআইআরসি এটি ডেটা ধরে রাখার জন্য চূড়ান্ত মেমরির 2x অবধি হতে পারে (ওয়েসের নিবন্ধ থেকে), তবে আমি মনে করি তিনি এটিকে একটি ধ্রুবক + চূড়ান্ত স্মৃতিতে নামিয়ে আনলেন
জেফ

আহ, আমাকে পুনরায় পড়তে হবে, আমি মনে করি 2x একটি নির্দিষ্ট অ্যালগরিদমের জন্য কিছু সুবিধাজনক তাত্ত্বিক ন্যূনতম হ'ল, যদি এটি কুলও কম হয়।
অ্যান্ডি হেডেন

আপনি দেখার জন্য (বাস্তব সময়ে) আইও পারফরম্যান্সের iotopমতো top/ ব্যবহার করতে পারেন can htop
ফিলিপ মেঘ

1
nbytesআপনার যদি ডেটাফ্রেমে উদাহরণস্বরূপ স্ট্রিং থাকে তবে এটি একটি স্থূল অবমূল্যায়ন হবে।
ওসা

10

আপনি যদি dtypeআপনার অ্যারের গুলি জানেন তবে আপনি পাইথন অবজেক্টের জন্য আপনার ডেটা + কিছু সঞ্চয় করতে এটি লাগবে এমন বাইটের সংখ্যাটি সরাসরি গণনা করতে পারেন। numpyঅ্যারেগুলির একটি দরকারী বৈশিষ্ট্য হ'ল nbytes। আপনি একটি পান্ডাস মধ্যে বিন্যাসগুলি থেকে বাইটের নম্বর পেতে পারি DataFrameকরে

nbytes = sum(block.values.nbytes for block in df.blocks.values())

objectdtype অ্যারেগুলি প্রতি বস্তুতে 8 বাইট সঞ্চয় করে রাখে (অবজেক্ট dtype অ্যারেগুলি একটি অস্বচ্ছকে পয়েন্টার সঞ্চয় করে PyObject), তাই আপনার সিএসভিতে যদি আপনার স্ট্রিং থাকে তবে আপনাকে অ্যাকাউন্টটি গ্রহণ করা উচিত যা সেইগুলিকে টাইপ অ্যারেগুলিতে read_csvপরিণত করবে objectএবং সেই অনুযায়ী আপনার গণনাগুলি সামঞ্জস্য করবে।

সম্পাদনা করুন:

এর আরও বিশদের জন্য numpyস্কেলারের ধরণের পৃষ্ঠাটি দেখুন object dtype। যেহেতু কেবল একটি রেফারেন্স সঞ্চিত রয়েছে আপনাকে অ্যারেতে অবজেক্টের আকারটিও বিবেচনায় নেওয়া উচিত। যেমন পৃষ্ঠাটি বলেছে, অবজেক্ট অ্যারেগুলি পাইথন listঅবজেক্টগুলির সাথে কিছুটা মিল ।


ধন্যবাদ ফিলিপ! কেবল স্পষ্ট করে বলার জন্য - একটি স্ট্রিংয়ের জন্য আমাদের স্ট্রিং অবজেক্টের পয়েন্টারটির জন্য 8 বাইট প্রয়োজন, প্লাস প্রকৃত স্ট্রিং অবজেক্ট?
আন

1
হ্যাঁ, যে কোনও অবজেক্টের ধরণের জন্য আপনার একটি 8 বাইট পয়েন্টার + আকার (অবজেক্ট)
লাগবে

1
সুপারিশ করুন df.blocks.values ​​() দেখে মনে হচ্ছে df.blocks এখন একটি ডিক
মরোকলিন

8

হ্যা এখানে. পান্ডারা আপনার ডেটাগুলি 2 টি মাত্রিক ন্যম্পি ndarrayস্ট্রাকচারে ডিটিপ্স দ্বারা গোষ্ঠীভুক্ত করবে। ndarrayমূলত একটি ছোট শিরোলেখ সহ একটি কাঁচা সি অ্যারের ডেটা। সুতরাং আপনি dtypeঅ্যারের মাত্রাগুলির সাথে এতে থাকা আকারের গুণকে কেবলমাত্র এটির আকারটি অনুমান করতে পারেন ।

উদাহরণস্বরূপ: আপনার যদি 2 np.int32এবং 5 np.float64কলাম সহ 1000 টি সারি থাকে তবে আপনার ডেটাফ্রেমে একটি 2x1000 np.int32অ্যারে এবং একটি 5x1000 np.float64অ্যারে থাকবে:

4 বাইটস * 2 * 1000 + 8 বাইটস * 5 * 1000 = 48000 বাইট


@ অ্যান্ডি হাইডেন আপনি নির্মাণ ব্যয়টি কী বলতে চান? একটি উদাহরণ আকার DataFrame?
ফিলিপ মেঘ

ধন্যবাদ ভিক্টর! @ অ্যান্ডি - নির্মাণ ব্যয় কত বড় কোনও ধারণা?
অ্যান

এটি অন্তর্ভুক্ত নয়, তবে সাইথনে এটি pandasএকটি খুব কার্যকর বাস্তবায়ন রয়েছে read_table(এটি নিমপীর লোডটেক্সটের তুলনায় অনেক ভাল) সুতরাং আমি ধরে নিই যে এটি সরাসরি ডেটা পার্স করে এবং সঞ্চয় করে ndarray
ভিক্টর কেরকেজ

@ ফিলিপক্লাউড আপনার এটি তৈরি করতে হবে, যা স্মৃতিশক্তি গ্রহণ করে .. মনে হচ্ছে যে আকারটি উল্লেখ করা হচ্ছে তার দ্বিগুণ মনে আছে? ...
অ্যান্ডি হেডেন

6

এটি আমি বিশ্বাস করি এটি পাইথনের যেকোন বস্তুকে ইন-মেমরি আকার দেয়। পান্ডা এবং নম্পী সম্পর্কিত অভ্যন্তরীণগুলি পরীক্ষা করা দরকার

>>> import sys
#assuming the dataframe to be df 
>>> sys.getsizeof(df) 
59542497
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.