আমি বেশ বড় পান্ডাস ডেটা ফ্রেমের সাথে কাজ করছি - আমার ডেটাসেটটি নীচের সেটআপটির অনুরূপ 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()
দুর্ভাগ্যক্রমে, পারফরম্যান্সটিও অসন্তুষ্টিজনক ছিল এবং আমি এই বিষয়টিতে যা পড়েছি তা থেকে পাইথনে লিখিত ইউডিএফ ফাংশনটি ব্যবহার করার বোঝা এবং সমস্ত পাইথন অবজেক্টগুলিকে স্পার্ক অবজেক্টে এবং পিছনে রূপান্তর করার জন্য প্রয়োজনীয় প্রয়োজন হতে পারে।
সুতরাং এখানে আমার প্রশ্নগুলি:
- সম্ভব হয় বাধাগুলি দূর করতে এবং কর্মক্ষমতা উন্নত করতে আমার দুটি পদ্ধতিরই সামঞ্জস্য করা যেতে পারে? (যেমন পাইসপার্ক সেটআপ, সাব-অনুকূল অপারেশনগুলি সামঞ্জস্য করা ইত্যাদি)
- তারা কি আরও ভাল বিকল্প আছে? পারফরম্যান্সের ক্ষেত্রে তারা প্রদত্ত সমাধানগুলির সাথে কীভাবে তুলনা করতে পারে?
dask
(((তাই আমার মন্তব্য এটা গবেষণার জন্য শুধু উপদেশ।