উপরের মন্তব্যগুলি থেকে মনে হয় এটি pandas
কিছু সময়ের জন্য পরিকল্পনা করা হয়েছে (একটি আকর্ষণীয়-চেহারা rosetta
প্রকল্পও যা আমি কেবল লক্ষ্য করেছি) just
যাইহোক, যতক্ষণ না প্রতিটি সমান্তরাল কার্যকারিতা এতে অন্তর্ভুক্ত করা হয় ততক্ষণ pandas
আমি লক্ষ্য করেছি যে pandas
সরাসরি cython
+ ওপেনএমপি এবং সি ++ ব্যবহার করে দক্ষ ও মেমরি-অনুলিপি সমান্তরাল বৃদ্ধি লিখতে খুব সহজ ।
সমান্তরাল গ্রুপবাই-সমষ্টি লেখার একটি ছোট উদাহরণ এখানে দেওয়া হয়েছে, যার ব্যবহার এইরকম:
import pandas as pd
import para_group_demo
df = pd.DataFrame({'a': [1, 2, 1, 2, 1, 1, 0], 'b': range(7)})
print para_group_demo.sum(df.a, df.b)
এবং আউটপুট হল:
sum
key
0 6
1 11
2 4
সন্দেহ করুন নিঃসন্দেহে, এই সাধারণ উদাহরণটির কার্যকারিতা শেষ পর্যন্ত এর অংশ হবে pandas
। কিছু জিনিস, কিন্তু, আরো কিছু সময়ের জন্য ++, সি parallelize প্রাকৃতিক হবে, এবং এটা কত সহজ এই একত্রিত হয় সচেতন হতে হবে গুরুত্বপূর্ণ pandas
।
এটি করতে, আমি একটি সাধারণ একক উত্স-ফাইল এক্সটেনশন লিখেছিলাম যার কোড অনুসরণ করে।
এটি কিছু আমদানি এবং টাইপ সংজ্ঞা দিয়ে শুরু হয়
from libc.stdint cimport int64_t, uint64_t
from libcpp.vector cimport vector
from libcpp.unordered_map cimport unordered_map
cimport cython
from cython.operator cimport dereference as deref, preincrement as inc
from cython.parallel import prange
import pandas as pd
ctypedef unordered_map[int64_t, uint64_t] counts_t
ctypedef unordered_map[int64_t, uint64_t].iterator counts_it_t
ctypedef vector[counts_t] counts_vec_t
সি ++ unordered_map
টাইপটি একটি একক থ্রেডের vector
যোগফলের জন্য এবং সমস্ত থ্রেডের দ্বারা সংমিশ্রণের জন্য।
এখন ফাংশন sum
। এটি দ্রুত অ্যাক্সেসের জন্য টাইপযুক্ত মেমরি ভিউগুলির সাথে শুরু হয় :
def sum(crit, vals):
cdef int64_t[:] crit_view = crit.values
cdef int64_t[:] vals_view = vals.values
ফাংশনটি আধা-সমানভাবে থ্রেডগুলিতে ভাগ করে (এখানে হার্ডকড করা 4) এবং প্রতিটি থ্রেডকে তার পরিসীমাতে প্রবেশের যোগফলগুলি যোগ করে চলতে থাকে:
cdef uint64_t num_threads = 4
cdef uint64_t l = len(crit)
cdef uint64_t s = l / num_threads + 1
cdef uint64_t i, j, e
cdef counts_vec_t counts
counts = counts_vec_t(num_threads)
counts.resize(num_threads)
with cython.boundscheck(False):
for i in prange(num_threads, nogil=True):
j = i * s
e = j + s
if e > l:
e = l
while j < e:
counts[i][crit_view[j]] += vals_view[j]
inc(j)
থ্রেডগুলি সম্পূর্ণ হয়ে গেলে, ফাংশনটি সমস্ত ফলাফলকে (বিভিন্ন শ্রেণির থেকে) একক মধ্যে একীভূত করে unordered_map
:
cdef counts_t total
cdef counts_it_t it, e_it
for i in range(num_threads):
it = counts[i].begin()
e_it = counts[i].end()
while it != e_it:
total[deref(it).first] += deref(it).second
inc(it)
যা বাকি আছে তা হ'ল একটি তৈরি করা DataFrame
এবং ফলাফলগুলি ফেরত দেওয়া:
key, sum_ = [], []
it = total.begin()
e_it = total.end()
while it != e_it:
key.append(deref(it).first)
sum_.append(deref(it).second)
inc(it)
df = pd.DataFrame({'key': key, 'sum': sum_})
df.set_index('key', inplace=True)
return df