পান্ডাদের ডেথফ্রেমে গ্রুপযুক্ত পাইথন ফাংশন প্রয়োগ করা - গণনার গতি বাড়ানোর সবচেয়ে দক্ষ পদ্ধতির কী?


9

আমি বেশ বড় পান্ডাস ডেটা ফ্রেমের সাথে কাজ করছি - আমার ডেটাসেটটি নীচের সেটআপটির অনুরূপ df:

import pandas as pd
import numpy  as np

#--------------------------------------------- SIZING PARAMETERS :
R1 =                    20        # .repeat( repeats = R1 )
R2 =                    10        # .repeat( repeats = R2 )
R3 =                541680        # .repeat( repeats = [ R3, R4 ] )
R4 =                576720        # .repeat( repeats = [ R3, R4 ] )
T  =                 55920        # .tile( , T)
A1 = np.arange( 0, 2708400, 100 ) # ~ 20x re-used
A2 = np.arange( 0, 2883600, 100 ) # ~ 20x re-used

#--------------------------------------------- DataFrame GENERATION :
df = pd.DataFrame.from_dict(
         { 'measurement_id':        np.repeat( [0, 1], repeats = [ R3, R4 ] ), 
           'time':np.concatenate( [ np.repeat( A1,     repeats = R1 ),
                                    np.repeat( A2,     repeats = R1 ) ] ), 
           'group':        np.tile( np.repeat( [0, 1], repeats = R2 ), T ),
           'object':       np.tile( np.arange( 0, R1 ),                T )
           }
        )

#--------------------------------------------- DataFrame RE-PROCESSING :
df = pd.concat( [ df,
                  df                                                  \
                    .groupby( ['measurement_id', 'time', 'group'] )    \
                    .apply( lambda x: np.random.uniform( 0, 100, 10 ) ) \
                    .explode()                                           \
                    .astype( 'float' )                                    \
                    .to_frame( 'var' )                                     \
                    .reset_index( drop = True )
                  ], axis = 1
                )

দ্রষ্টব্য: একটি ন্যূনতম উদাহরণ থাকার উদ্দেশ্যে, এটি সহজেই সাবসেট করা যেতে পারে (উদাহরণস্বরূপ df.loc[df['time'] <= 400, :]), তবে যেহেতু আমি যেভাবেই ডেটা সিমুলেটেড করেছিলাম ভেবেছিলাম যে মূল আকারটি আরও ভাল ওভারভিউ দেবে।

সংজ্ঞায়িত প্রতিটি গ্রুপের জন্য ['measurement_id', 'time', 'group']আমাকে নিম্নলিখিত ফাংশনটি কল করতে হবে:

from sklearn.cluster import SpectralClustering
from pandarallel     import pandarallel

def cluster( x, index ):
    if len( x ) >= 2:
        data = np.asarray( x )[:, np.newaxis]
        clustering = SpectralClustering( n_clusters   =  5,
                                         random_state = 42
                                         ).fit( data )
        return pd.Series( clustering.labels_ + 1, index = index )
    else:
        return pd.Series( np.nan, index = index )

পারফরম্যান্স বাড়ানোর জন্য আমি দুটি পদ্ধতির চেষ্টা করেছি:

প্যানডেরালাল প্যাকেজ

প্রথম পন্থাটি pandarallelপ্যাকেজ ব্যবহার করে গণনার সমান্তরাল ছিল :

pandarallel.initialize( progress_bar = True )
df \
  .groupby( ['measurement_id', 'time', 'group'] ) \
  .parallel_apply( lambda x: cluster( x['var'], x['object'] ) )

তবে এটি সাব-অপটিমাল বলে মনে হচ্ছে কারণ এটি প্রচুর র‍্যাম গ্রহণ করে এবং সমস্ত কোর গণনে ব্যবহৃত হয় না (এমনকি pandarallel.initialize()পদ্ধতিতে কোরের সংখ্যা নির্দিষ্ট করে উল্লেখ করেও )। এছাড়াও, কখনও কখনও বিভিন্ন ত্রুটি দিয়ে গণনাগুলি সমাপ্ত হয়, যদিও এর কারণগুলির জন্য আমার সম্ভবত কোনও কারণ খুঁজে পাওয়ার সুযোগ হয়নি (সম্ভবত র্যামের অভাব?)।

পাইস্পার্ক পান্ডাস ইউডিএফ

আমি একটি স্পার্ক পান্ডাস ইউডিএফও গিয়েছিলাম, যদিও আমি স্পার্কে সম্পূর্ণ নতুন। এখানে আমার প্রচেষ্টা:

import findspark;  findspark.init()

from pyspark.sql           import SparkSession
from pyspark.conf          import SparkConf
from pyspark.sql.functions import pandas_udf, PandasUDFType
from pyspark.sql.types     import *

spark = SparkSession.builder.master( "local" ).appName( "test" ).config( conf = SparkConf() ).getOrCreate()
df = spark.createDataFrame( df )

@pandas_udf( StructType( [StructField( 'id', IntegerType(), True )] ), functionType = PandasUDFType.GROUPED_MAP )
def cluster( df ):
    if len( df['var'] ) >= 2:
        data = np.asarray( df['var'] )[:, np.newaxis]
        clustering = SpectralClustering( n_clusters   =  5,
                                         random_state = 42
                                         ).fit( data )
        return pd.DataFrame( clustering.labels_ + 1,
                             index = df['object']
                             )
    else:
        return pd.DataFrame( np.nan,
                             index = df['object']
                             )

res = df                                           \
        .groupBy( ['id_half', 'frame', 'team_id'] ) \
        .apply( cluster )                            \
        .toPandas()

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

সুতরাং এখানে আমার প্রশ্নগুলি:

  1. সম্ভব হয় বাধাগুলি দূর করতে এবং কর্মক্ষমতা উন্নত করতে আমার দুটি পদ্ধতিরই সামঞ্জস্য করা যেতে পারে? (যেমন পাইসপার্ক সেটআপ, সাব-অনুকূল অপারেশনগুলি সামঞ্জস্য করা ইত্যাদি)
  2. তারা কি আরও ভাল বিকল্প আছে? পারফরম্যান্সের ক্ষেত্রে তারা প্রদত্ত সমাধানগুলির সাথে কীভাবে তুলনা করতে পারে?

2
আপনি কী গবেষণা করেছেন ?
দানিলা গণচর

1
এখনও নয়, তবে আপনার পরামর্শের জন্য ধন্যবাদ - আমি এটি দিয়ে যাব
কুবা_

দুর্ভাগ্যবশত আমি কাজ করে নি dask(((তাই আমার মন্তব্য এটা গবেষণার জন্য শুধু উপদেশ।
Danila Ganchar

পারফরম্যান্স দ্বারা আমি বোঝাচ্ছিলাম এমন সময় যেখানে গণনা শেষ করা যায়।
কুবা_

উত্তর:


1

প্রশ্নঃ : " গেল আমার পন্থা পারেন স্থায়ী করা যেতে সম্ভব bottlenecks নিষ্কাশন এবং কর্মক্ষমতা উন্নত? (যেমন PySpark সেটআপ, উপ-অনুকূল অপারেশন সামঞ্জস্য ইত্যাদি) "

+1উল্লেখ জন্য সেটআপ অ্যাড-অন ওভারহেড খরচ কম্পিউটিং উভয় কৌশল জন্য। এটি সর্বদা একটি বিরতিযুক্ত বিন্দুতে পরিণত হয়, কেবলমাত্র পরে একটি অ- [SERIAL]কৌশলটি কিছু কামনা-করা [TIME]ডোমেন স্পিডআপের কোনও উপকারজনক আনন্দ অর্জন করতে পারে (তবুও যদি [SPACE]অন্যভাবে হয় তবে সাধারণত ডোমেনের জন্য অনুমতি দেওয়া হয় বা সম্ভব হয় - হ্যাঁ, র‌্যাম)। .. এমন আকারের ডিভাইস, বাজেট এবং অন্যান্য অনুরূপ বাস্তব-বিশ্বের সীমাবদ্ধতার অস্তিত্ব এবং অ্যাক্সেস)

প্রথমত,
প্রাক-উড্ডয়ন পরীক্ষা, আমরা নিতে বন্ধ
নতুন, ওভারহেড-কঠোর Amdahl এর আইন প্রণয়নের বর্তমানে অ্যাড-অন এই দুটি নিগমবদ্ধ করতে সক্ষম হয় overheads সহ বিরতি-এমনকি সাধনযোগ্য Speedup-মাত্রা পূর্বাভাসের এই প্রতিফলিত পয়েন্ট, যেহেতু এটি অর্থবহুল হয়ে উঠতে পারে (ব্যয় / প্রভাব, দক্ষতার অর্থে) সমান্তরালে যেতে।
pSO + pTO

এখানে চিত্র বর্ণনা লিখুন

তবুও,
যে না আমাদের মূল সমস্যা এখানে
এটি পরবর্তী আসে:

এর পরে,
গণনার ব্যয়গুলি দেওয়া SpectralClustering(), যা এখানে র‌্যাডিয়াল বোল্টজমান ফাংশন কার্নেলটি ব্যবহার করতে চলেছে ~ exp( -gamma * distance( data, data )**2 )মনে হয় সংজ্ঞা অনুসারে dataকোনও সংখ্যক বিচ্ছিন্ন ওয়ার্ক-ইউনিটকে-কম্পোজেন্টের বিভাজন থেকে কোনও অগ্রগতি হতে পারে না distance( data, data )to সমস্ত dataউপাদানসমূহ দেখুন (রেফারেন্স। যে কোনও-থেকে-কোনও মান-উত্তীর্ণ- { process | node }বিতরণিত টোপোলজির যোগাযোগ ব্যয়গুলি সুস্পষ্ট কারণে, - { process | node }বিতরণকৃত প্রসেসিংয়ের জন্য সবচেয়ে খারাপ ব্যবহারের ক্ষেত্রে না হলে ভয়াবহভাবে খারাপ হয় , যদি সরল বিরোধী নিদর্শন না হয় (কিছু সত্যই আরকেন বাদে, মেমরি-কম / স্টেট-কম, তবে কম্পিউটিং কাপড়)।

পেডেন্টিক বিশ্লেষকদের জন্য, হ্যাঁ - এটিকে যুক্ত করুন (এবং আমরা ইতিমধ্যে একটি খারাপ অবস্থা বলতে পারি ) - আবার - যে কোনও- কে-কে-মানে- প্রসেসিংয়ের জন্য, এখানে O( N^( 1 + 5 * 5 ) )যা ঘটে যায়, জন্য N ~ len( data ) ~ 1.12E6+, আমাদের কিছু পাওয়ার ইচ্ছার বিরুদ্ধে ভয়াবহভাবে স্মার্ট এবং দ্রুত প্রক্রিয়াকরণ

তাতে কি?

সেটআপ খরচ উপেক্ষিত না হয়, বর্ধিত যোগাযোগ খরচ প্রায় উপরে অঙ্কিত প্রচেষ্টা ব্যবহার থেকে নিশ্চিত অক্ষম কোনো উন্নতির জন্য একটি pure- থেকে সরাতে হবে [SERIAL]কিছু ফর্ম মধ্যে প্রক্রিয়া প্রবাহ মাত্র - [CONCURRENT]বা True- [PARALLEL]কিছু কাজ-উপ-ইউনিট অর্কেস্ট্রারচনা , যে কোনও-থেকে-কোনও মান-উত্তীর্ণ টোপোলজিকে বাস্তবায়নের জন্য অবশ্যই আবশ্যক সম্পর্কিত একটি ওভারহেডগুলি বাড়ানো (এক ট্যান্ডেম জোড়)

এটা যদি তাদের জন্য না হত?

ঠিক আছে, এটি একটি কম্পিউটিং সায়েন্স অক্সিমারন হিসাবে শোনাচ্ছে - এটি সম্ভব হলেও, যে কোনও প্রাক-গণিত দূরত্বের [TIME]খরচগুলি (যা সেই বিশাল- ডোমেন জটিলতার জন্য "আগেই" নেওয়া হত (কোথায়? কীভাবে? কোনও কি আছে? অন্যটি, অ-এড়াতে পারা যায় এমন বিলম্বিতা, কোনও কোনও দ্বারা সম্ভাব্য বিলম্বিত মাস্কিংয়ের অনুমতি দেওয়া (এখনও অবধি অজানা) ভবিষ্যতে কোনও-থেকে-কোনও দূরত্বের ম্যাট্রিক্সের বর্ধনমূলক নির্মাণের অনুমতি দেওয়া হবে) তবে মূলত উপস্থিত ব্যয়গুলি অন্য কোনও স্থানে প্রতিস্থাপন করবে would [TIME]- এবং- [SPACE]ডোমেনস, তাদের 'হ্রাস না।

প্রশ্ন : "তারা কি আরও ভাল বিকল্প আছে? "

একমাত্র, আমি অবধি অবহিত, চেষ্টা করে দেখা হচ্ছে, যদি সমস্যাটি অন্য একটি, আবার কিউও-সূত্রযুক্ত, সমস্যার ফ্যাশন-তে রূপান্তরিত করা সম্ভব হয় (রেফারেন্স: কিউ ইউয়ান্টাম- ইউ এনকন্ট্রাইনড- বি ইনারি- হে প্রেমেসেশন) , সুসংবাদটি হ'ল এটি করার সরঞ্জামগুলি, প্রথম হাতের জ্ঞানের একটি ভিত্তি এবং ব্যবহারিক সমস্যা সমাধানের অভিজ্ঞতার উপস্থিতি রয়েছে এবং আরও বড় হয়)

প্রশ্ন : পারফরম্যান্সের ক্ষেত্রে তারা প্রদত্ত সমাধানগুলির সাথে কীভাবে তুলনা করে ?

পারফরম্যান্সটি শ্বাসরুদ্ধকর - কিউবিও-সূচিত সমস্যাটির একটি O(1)ধ্রুবক সময়ে ( [TIME]-ডোমাইন) একটি প্রতিশ্রুতিশীল (!) দ্রাবক এবং -ডোমাইন কিছুটা সীমাবদ্ধ রয়েছে [SPACE](যেখানে সম্প্রতি ঘোষণা করা এলএলএনএল কৌশলগুলি এই শারীরিক জগতকে এড়াতে সহায়তা করতে পারে, বর্তমান কিউপিউ বাস্তবায়ন, সমস্যার সীমাবদ্ধতা) মাপ)।


এটি একটি আকর্ষণীয় উত্তর, তবে বিষয়টি মনে হচ্ছে না - ওপি একাধিক ছোট মডেলকে প্রশিক্ষণ দেয়, একটিও নয়। সুতরাং আপনার মূল পর্যবেক্ষণ বেশিরভাগ অপ্রাসঙ্গিক।
ব্যবহারকারী 10938362

@ user10938362 আপনার দাবি করা সম্পত্তি ( ছোট মডেলদের প্রশিক্ষণ ) কীভাবে প্রসেসিং ব্যয়ের উপরে পোস্ট করা বিগ-ও মেট্রিক ছাড়া অন্য কোনওটিতে অনুবাদ করে? নিশ্চিত যে অনেক ছোট মডেল একটি তাত্ত্বিকভাবে কেবল লিনিয়ারલી ক্রমবর্ধমান সমষ্টি (এখনও) বিজন-ও পৃথক ব্যয়ের (এখন এন-এর চেয়ে ছোট, তবে অন্য কারণগুলিতে নয়) প্রসেসিংয়ের প্রতিশ্রুতি দেয়, তবুও, আপনাকে এগুলিতে আরও একটি ব্যয়বহুল ব্যয় যোগ করতে হবে সেটআপ- এবং টার্মিনেশন-ওভারহেড উভয় ব্যয়ের সাথে অ্যাড-অনের খরচ এবং সমস্ত অ্যাড-অন যোগাযোগ-ওভারহেড ব্যয় (পরামিতি / ডেটা / ফলাফল + সাধারণত প্রতিটি ধাপে সের / ডিইএস প্রসেসিংয়ের ব্যয়)
ইউজার 3666197

0

এটি কোনও উত্তর নয়, তবে ...

আপনি যদি চালান

df.groupby(['measurement_id', 'time', 'group']).apply(
    lambda x: cluster(x['var'], x['object']))

(অর্থাত্ একা পান্ডাসের সাথে), আপনি লক্ষ্য করবেন যে আপনি ইতিমধ্যে কয়েকটি কোর ব্যবহার করছেন। কাজটি সমান্তরাল করতে ডিফল্টরূপে sklearnব্যবহারের কারণ joblibএটি। আপনি করতে পারেন Dask পক্ষে নির্ধারণকারী আউট অদলবদল এবং সম্ভবত থ্রেড মধ্যে ডেটা ভাগ উপর আরো বেশি দক্ষতা, কিন্তু এতক্ষণ কাজ আপনি করছেন হিসাবে CPU- র-বাউন্ড এই মত কিছুই আপনি এটা গতি বাড়াতে আপ করতে পারেন হবে।

সংক্ষেপে, এটি একটি অ্যালগরিদম সমস্যা: এটির কম্পিউটিংয়ের জন্য বিভিন্ন ফ্রেমওয়ার্কগুলি বিবেচনা করার আগে আপনাকে কী গণনা করা দরকার তা নির্ধারণ করুন।


আপনি কি দয়া করে ব্যাখ্যা করতে পারেন যে আপনি যখন ওয়ার্ক-স্প্লিট- স্পাড প্রক্রিয়া দ্বারা সংগঠিত করা হয়েছিল, " থ্রেডগুলির মধ্যে ডেটা ভাগ করা ..." উল্লেখ করেন কেন , থ্রেডগুলির সাথে কোনও সম্পর্ক নেই, ভাগ করে নেওয়া কম? যুক্তিগুলির আপনার সদয় ব্যাখ্যা করার জন্য আপনাকে ধন্যবাদ। joblib
ব্যবহারকারী3666197

ঠিক যেমন, jboblib সাধারণত প্রক্রিয়াগুলি ব্যবহার করে তবে এটি বিকল্পভাবে ব্যাকএন্ড হিসাবে ড্যাস্ক ব্যবহার করতে পারে, যেখানে আপনি আপনার থ্রেড এবং প্রক্রিয়াগুলির মিশ্রণটি চয়ন করতে পারেন।
14 জুলাই

আমি সমান্তরাল কম্পিউটিংয়ের জন্য এক ধরণের নবাগত, তবে স্ক্লার্ন সমান্তরাল ব্যবহার করলেও কী এই সেটিংসে এটি অকেজো নয়? মানে, স্ক্লার্ন দ্বারা সম্পাদিত ক্রিয়াকলাপগুলি অত্যন্ত সহজ কারণ প্রতিটি ক্লাস্টারিং অপারেশন কেবলমাত্র 10 পয়েন্টে প্রয়োগ করা হয়। আবার, আমি এখানে ভুল হতে পারি, কিন্তু আমি মনে করি যেভাবে আমরা কীভাবে মূল ডেটার প্রসেসিংয়ের অংশগুলিকে সমান্তরাল করি সেটাই আসল সমস্যা।
কুবা_

"এটা এই সেটিংসে বেহুদা নয়" - ভাল, আপনি কর্মক্ষমতা 8 CPU- র কোর 'মূল্য পরিবর্তে 1. ব্যবহার
mdurant

0

আমি এতে বিশেষজ্ঞ নই Dask, তবে আমি নীচের কোডটি বেসলাইন হিসাবে সরবরাহ করি:

import dask.dataframe as ddf

df = ddf.from_pandas(df, npartitions=4) # My PC has 4 cores

task = df.groupby(["measurement_id", "time", "group"]).apply(
    lambda x: cluster(x["var"], x["object"]),
    meta=pd.Series(np.nan, index=pd.Series([0, 1, 1, 1])),
)

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