পান্ডাস প্রয়োগের ক্ষেত্রে সমান্তরালতার বিষয়ে এই প্রশ্নের আরও সাধারণ সংস্করণ রয়েছে - সুতরাং এটি একটি সতেজ প্রশ্ন :)
প্রথমত , আমি সুইফটারটি উল্লেখ করতে চাইছি যেহেতু আপনি "প্যাকেজড" সমাধান চেয়েছিলেন, এবং এটি পান্ডাস সমান্তরালতা সম্পর্কিত বেশিরভাগ SO প্রশ্নের উপরে উপস্থিত হয়।
তবে .. আমি এখনও এটির জন্য আমার ব্যক্তিগত গিস্ট কোডটি ভাগ করে নিতে চাই, যেহেতু ডেটাফ্রেমের সাথে বেশ কয়েক বছর কাজ করার পরে আমি কখনই 100% সমান্তরাল সমাধান খুঁজে পাইনি (মূলত প্রয়োগ ফাংশনের জন্য) এবং আমাকে সর্বদা আমার ফিরে আসতে হয়েছিল " ম্যানুয়াল "কোড।
আপনাকে ধন্যবাদ আমি যেকোনও (তাত্ত্বিকভাবে) ডেটা ফ্রেম পদ্ধতির নাম অনুসারে সমর্থন করা আরও জেনারিক করে তুলেছি (যাতে আপনার আইসিনের জন্য সংস্করণ রাখতে হবে না, প্রয়োগ করতে হবে ইত্যাদি ইত্যাদি)।
আমি এটি পাইথন 2.7 এবং 3.6 উভয় ব্যবহার করে "ইসিন", "প্রয়োগ" এবং "ইসনা" ফাংশনে পরীক্ষা করেছি tested এটি 20 লাইনের নীচে এবং আমি "সাবসেট" এবং "এনজবস" এর মতো পান্ডার নামকরণের কনভেনশনটি অনুসরণ করেছি।
আমি "আইসিন" এর জন্য দশকের সমতুল্য কোডের সাথে একটি সময়ের তুলনাও যুক্ত করেছি এবং মনে হয় this এক্স 2 গুণ এই ধরণের পরে er
এটিতে 2 টি কার্য রয়েছে:
df_m মাল্টি_কোর - এটিই আপনি কল করেন। এটি গ্রহণ করে:
- আপনার ডিএফ অবজেক্ট
- আপনি যে ফাংশনটির নাম কল করতে চান
- কলামগুলির উপসেটটি ফাংশনটি সম্পাদন করা যায় (সময় / স্মৃতি হ্রাস করতে সহায়তা করে)
- সমান্তরালভাবে চালনার কাজের সংখ্যা (-1 বা সমস্ত কোরের জন্য বাদ)
- ডিএফ এর ক্রিয়াকলাপ অন্য কোনও কোয়ার্গাগুলি গ্রহণ করে ("অক্ষ" এর মতো)
_ডিএফ_স্প্লিট - এটি একটি অভ্যন্তরীণ সহায়ক ফাংশন যা চলমান মডিউলে বিশ্বব্যাপী অবস্থান করতে হবে (পুল.ম্যাপ "প্লেসমেন্ট নির্ভর"), অন্যথায় আমি এটি অভ্যন্তরীণভাবে সনাক্ত করতে পারি ..
আমার সংক্ষেপে কোডটি এখানে রয়েছে (আমি সেখানে আরও পান্ডাস ফাংশন পরীক্ষা যুক্ত করব):
import pandas as pd
import numpy as np
import multiprocessing
from functools import partial
def _df_split(tup_arg, **kwargs):
split_ind, df_split, df_f_name = tup_arg
return (split_ind, getattr(df_split, df_f_name)(**kwargs))
def df_multi_core(df, df_f_name, subset=None, njobs=-1, **kwargs):
if njobs == -1:
njobs = multiprocessing.cpu_count()
pool = multiprocessing.Pool(processes=njobs)
try:
splits = np.array_split(df[subset], njobs)
except ValueError:
splits = np.array_split(df, njobs)
pool_data = [(split_ind, df_split, df_f_name) for split_ind, df_split in enumerate(splits)]
results = pool.map(partial(_df_split, **kwargs), pool_data)
pool.close()
pool.join()
results = sorted(results, key=lambda x:x[0])
results = pd.concat([split[1] for split in results])
return results
বেলো একটি সমান্তরাল আইসিনের জন্য একটি পরীক্ষার কোড , দেশী, বহু-কোর গিস্ট এবং ডাস্ক পারফরম্যান্সের সাথে তুলনা করে। 8 টি শারীরিক কোর সহ একটি আই 7 মেশিনে, আমি প্রায় X4 বার স্পিডআপ পেয়েছি। আপনি আপনার সত্যিকারের ডেটাতে যা পেয়েছেন তা শুনতে আমি পছন্দ করব!
from time import time
if __name__ == '__main__':
sep = '-' * 50
# isin test
N = 10000000
df = pd.DataFrame({'c1': np.random.randint(low=1, high=N, size=N), 'c2': np.arange(N)})
lookfor = np.random.randint(low=1, high=N, size=1000000)
print('{}\ntesting pandas isin on {}\n{}'.format(sep, df.shape, sep))
t1 = time()
print('result\n{}'.format(df.isin(lookfor).sum()))
t2 = time()
print('time for native implementation {}\n{}'.format(round(t2 - t1, 2), sep))
t3 = time()
res = df_multi_core(df=df, df_f_name='isin', subset=['c1'], njobs=-1, values=lookfor)
print('result\n{}'.format(res.sum()))
t4 = time()
print('time for multi core implementation {}\n{}'.format(round(t4 - t3, 2), sep))
t5 = time()
ddata = dd.from_pandas(df, npartitions=njobs)
res = ddata.map_partitions(lambda df: df.apply(apply_f, axis=1)).compute(scheduler='processes')
t6 = time()
print('result random sample\n{}'.format(res.sample(n=3, random_state=0)))
print('time for dask implementation {}\n{}'.format(round(t6 - t5, 2), sep))
--------------------------------------------------
testing pandas isin on (10000000, 2)
--------------------------------------------------
result
c1 953213
c2 951942
dtype: int64
time for native implementation 3.87
--------------------------------------------------
result
c1 953213
dtype: int64
time for multi core implementation 1.16
--------------------------------------------------
result
c1 953213
c2 951942
dtype: int64
time for dask implementation 2.88