python - Pandas সঙ্গে তথ্য ফ্রেম মাধ্যমে লুপ সবচেয়ে দক্ষ উপায় কি?
performance dataframe (7)
Pandas NumPy অ্যারে উপর ভিত্তি করে। NumPy অ্যারেগুলির সাথে গতির কীটি একবারে সমগ্র সারিতে আপনার ক্রিয়াকলাপগুলি সঞ্চালন করা হয় না, সারি দ্বারা সারি বা আইটেম-বাই-আইটেমটি না।
উদাহরণস্বরূপ, যদি close
হয় 1-ডি অ্যারের, এবং আপনি দিন-দিন-দিন পরিবর্তন চান,
pct_change = close[1:]/close[:-1]
এটি পরিবর্তে শতাংশ পরিবর্তনের সমগ্র অ্যারেকে এক বিবৃতি হিসাবে গণনা করে
pct_change = []
for row in close:
pct_change.append(...)
সুতরাং for i, row in enumerate(...)
পাইথন লুপ এড়ানোর চেষ্টা করুন for i, row in enumerate(...)
সংখ্যাটি ... (সম্পূর্ণরূপে) করুন এবং সারির সারির পরিবর্তে সম্পূর্ণ অ্যারের (বা ডেটাফ্রেম) সম্পূর্ণরূপে ক্রিয়াকলাপগুলির সাথে আপনার হিসাবগুলি কীভাবে সম্পাদন করবেন তা নিয়ে চিন্তা করুন।
আমি ক্রমানুসার পদ্ধতিতে ডেটাফ্রেমে আর্থিক তথ্যগুলিতে আমার নিজের জটিল ক্রিয়াকলাপগুলি সম্পাদন করতে চাই।
উদাহরণস্বরূপ, আমি ইয়াহু ফাইন্যান্স থেকে নেওয়া নিম্নলিখিত MSFT CSV ফাইলটি ব্যবহার করছি:
Date,Open,High,Low,Close,Volume,Adj Close
2011-10-19,27.37,27.47,27.01,27.13,42880000,27.13
2011-10-18,26.94,27.40,26.80,27.31,52487900,27.31
2011-10-17,27.11,27.42,26.85,26.98,39433400,26.98
2011-10-14,27.31,27.50,27.02,27.27,50947700,27.27
....
আমি তারপর নিম্নলিখিত কাজ করি:
#!/usr/bin/env python
from pandas import *
df = read_csv('table.csv')
for i, row in enumerate(df.values):
date = df.index[i]
open, high, low, close, adjclose = row
#now perform analysis on open/close based on date, etc..
যে সবচেয়ে কার্যকর উপায়? পন্ডাসের গতিতে ফোকাস দেওয়া, আমি মনে করি মূল্যের মাধ্যমে পুনরাবৃত্তি করার জন্য কিছু বিশেষ ফাংশন থাকতে হবে যাতে একটি সূচী পুনরুদ্ধার করে (সম্ভবত জেনারেটরের মাধ্যমে মেমরি দক্ষ হতে পারে)? df.iteritems
দুর্ভাগ্যবশত শুধুমাত্র কলাম দ্বারা কলাম পুনরাবৃত্তি।
আগের মত উল্লেখ করা হয়েছে, প্যান্ডাস বস্তু একবারে সম্পূর্ণ অ্যারে প্রক্রিয়া করার সময় সবচেয়ে কার্যকর। তবে যারা সত্যিই আমার মত কিছু সঞ্চালনের জন্য প্যান্ডাস ডেটাফ্রেমের মাধ্যমে লুপ করতে চায় তাদের জন্য, আমি এটি করার জন্য অন্তত তিনটি উপায় খুঁজে পেয়েছি। আমি একটি সংক্ষিপ্ত পরীক্ষা করেছেন তিনটি কোনটি অন্তত সময় গ্রহণ করা হয় তা দেখতে।
t = pd.DataFrame({'a': range(0, 10000), 'b': range(10000, 20000)})
B = []
C = []
A = time.time()
for i,r in t.iterrows():
C.append((r['a'], r['b']))
B.append(time.time()-A)
C = []
A = time.time()
for ir in t.itertuples():
C.append((ir[1], ir[2]))
B.append(time.time()-A)
C = []
A = time.time()
for r in zip(t['a'], t['b']):
C.append((r[0], r[1]))
B.append(time.time()-A)
print B
ফলাফল:
[0.5639059543609619, 0.017839908599853516, 0.005645036697387695]
এটি সম্ভবত সময় ব্যয় পরিমাপ করার সেরা উপায় নয় তবে এটি আমার জন্য দ্রুত।
এখানে কিছু পেশাদার এবং বিপরীত IMHO হয়:
- .iterrows (): পৃথক ভেরিয়েবলগুলিতে সূচী এবং সারি আইটেমগুলি, কিন্তু উল্লেখযোগ্যভাবে ধীর
- .itertuples (): .iterrows () থেকে দ্রুত, তবে সারি আইটেমগুলির সাথে একত্রিত হওয়া সূচী, আইআর [0] সূচক
- জিপ: দ্রুততম, কিন্তু সারির সূচী কোন এক্সেস
আপনি ট্রান্সপোজিং করে সারির মাধ্যমে লুপ এবং তারপরে এটিরাইটমিং কল করতে পারেন:
for date, row in df.T.iteritems():
# do some logic here
আমি যে ক্ষেত্রে দক্ষতা সম্পর্কে নিশ্চিত নই। একটি পুনরাবৃত্ত অ্যালগরিদমে সর্বোত্তম সম্ভাব্য কর্মক্ষমতা পেতে, আপনি এটি cython লেখার অন্বেষণ করতে চাইতে পারেন, যাতে আপনি এমন কিছু করতে পারেন:
def my_algo(ndarray[object] dates, ndarray[float64_t] open,
ndarray[float64_t] low, ndarray[float64_t] high,
ndarray[float64_t] close, ndarray[float64_t] volume):
cdef:
Py_ssize_t i, n
float64_t foo
n = len(dates)
for i from 0 <= i < n:
foo = close[i] - open[i] # will be extremely fast
আমি প্রথম বিশুদ্ধ পাইথন এ অ্যালগরিদম লেখার সুপারিশ করব, এটি নিশ্চিত করে যে এটি কীভাবে কাজ করে এবং এটি কত দ্রুত হয় - যদি এটি যথেষ্ট দ্রুত না হয় তবে কমপক্ষে কাজটির মতো জিনিসটি সিথন এ রূপান্তর করুন যাতে হাতের-কোডেড সি হিসাবে দ্রুত কিছু পাওয়া যায়। / সি ++।
উত্তরটি iterrows
পরে আমি iterrows
চেক আউট iterrows
, কিন্তু এটি পাওয়া গেছে যে এটি ফলন করে (সূচী, সিরিজ) টিপল। আপনার জন্য ভাল কাজ করবে তা নিশ্চিত না, তবে আমার সমস্যাটির জন্য itertuples
পদ্ধতিটি ব্যবহার করে শেষ হয়ে গেছে, যা ফলন করে (সূচী, সারি_মূল্য ... ...) টিপল।
iterkv
এছাড়াও আছে, যা মাধ্যমে পুনরাবৃত্তি (কলাম, সিরিজ) tuples।
নিশ্চিতভাবে, ডেটাফ্রেমের উপর পুনরাবৃত্তি করার দ্রুততম উপায়টি ডিফল্ট numpy ndarray অ্যাক্সেস করতে হয় df.values
(যেমন আপনি করবেন) অথবা প্রতিটি কলামে পৃথকভাবে df.column_name.values
অ্যাক্সেস করে। যেহেতু আপনি df.index.values
অ্যাক্সেস পেতে চান তাই আপনি df.index.values
জন্য df.index.values
ব্যবহার করতে পারেন।
index = df.index.values
column_of_interest1 = df.column_name1.values
...
column_of_interestk = df.column_namek.values
for i in range(df.shape[0]):
index_value = index[i]
...
column_value_k = column_of_interest_k[i]
পাইথনিক না? অবশ্যই। কিন্তু দ্রুত।
যদি আপনি লুপের বাইরে আরো রস cython চান তবে আপনি cython দেখতে cython । Cython আপনি বিশাল speedups পেতে হবে (10x-100x মনে)। সর্বাধিক কর্মক্ষমতা জন্য সাইথন জন্য মেমরি মতামত পরীক্ষা।
পাণ্ডাসের নতুন সংস্করণগুলি এখন সারিগুলির পুনরাবৃত্তি করার জন্য একটি অন্তর্নির্মিত ফাংশন অন্তর্ভুক্ত করে।
for index, row in df.iterrows():
# do some logic here
অথবা, যদি আপনি এটি দ্রুততর itertuples()
ব্যবহার করতে চান itertuples()
কিন্তু, সারি পুনরাবৃত্তি এড়ানোর জন্য নুন্যি ফাংশন ব্যবহার করার unutbu এর পরামর্শ দ্রুততম কোড তৈরি করবে।
joris উল্লেখ করেছেন যে, iterrows
তুলনায় অনেক ধীরে ধীরে ধীরে ধীরে এবং itertuples
প্রায় 100 বার ইটারোর চেয়ে বেশি iterrows
এবং আমি 5027505 এর সাথে ডেটাফ্রেমে উভয় পদ্ধতির গতি পরীক্ষা করে দেখি ফলাফলটি iterrows
জন্য এটি 1200it / s, এবং itertuples
120000it / সেকেন্ড।
আপনি যদি itertuples
ব্যবহার করেন itertuples
নোট করুন যে লুপের প্রতিটি উপাদান একটি নামকরণযোগ্য, তাই প্রতিটি কলামে মানটি পেতে, আপনি নিম্নলিখিত উদাহরণ কোডটি উল্লেখ করতে পারেন
>>> df = pd.DataFrame({'col1': [1, 2], 'col2': [0.1, 0.2]},
index=['a', 'b'])
>>> df
col1 col2
a 1 0.1
b 2 0.2
>>> for row in df.itertuples():
... print(row.col1, row.col2)
...
1, 0.1
2, 0.2