पंडों को पायथन फंक्शन लागू करना डेटाफ़्रेम को समूहीकृत करना - संगणना को गति देने के लिए सबसे कुशल दृष्टिकोण क्या है?


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. क्या मेरे किसी भी दृष्टिकोण को संभावित बाधाओं को खत्म करने और प्रदर्शन में सुधार करने के लिए समायोजित किया जा सकता है? (उदाहरण PySpark सेटअप, उप-इष्टतम संचालन आदि को समायोजित करना)
  2. क्या वे कोई बेहतर विकल्प हैं? प्रदर्शन के संदर्भ में वे प्रदान किए गए समाधानों की तुलना कैसे करते हैं?

2
आप शोध किया dask ?
Danila Ganchar

1
अभी तक नहीं, लेकिन आपके सुझाव के लिए धन्यवाद - मैं इसे जाने
दूंगा

दुर्भाग्य से मैंने काम नहीं किया dask((मेरी टिप्पणी है, तो यह शोध के लिए सिर्फ सलाह है।
Danila Ganchar

प्रदर्शन से मेरा मतलब उस समय से था जिसमें गणना समाप्त की जा सकती है।
कुबा_

जवाबों:


1

क्यू : " सका मेरी किसी उपाय का समायोजित किया जा संभव बाधाओं को खत्म करने और प्रदर्शन में सुधार के लिए? (जैसे PySpark सेटअप, उप इष्टतम संचालन का समायोजन आदि) "

+1कंप्यूटिंग की रणनीति के लिए सेटअप एड-ऑन ओवरहेड लागत का उल्लेख करने के लिए। यह हमेशा ब्रेक-ईवन बिंदु बनाता है, जिसके बाद ही एक गैर- [SERIAL]रणनीति कुछ काम-का-के [TIME]-Domain स्पीडअप (फिर भी, यदि अन्य, आम तौर पर [SPACE]-Domain लागत परमिट या रहने योग्य - हाँ, RAM) के किसी भी लाभकारी आनन्द को प्राप्त कर सकता है । .. इस तरह के आकार के उपकरण, बजट और इसी तरह की वास्तविक दुनिया की बाधाओं के अस्तित्व का उपयोग)

सबसे पहले,
उड़ान-पूर्व जांच, इससे पहले कि हम टेक-ऑफ
नई, भूमि के ऊपर-सख्त Amdahl कानून के निर्माण वर्तमान में ऐड-ऑन इन दोनों को शामिल करने में सक्षम है ओवरहेड्स और सहित ब्रेक-ईवन प्राप्त स्पीड अप स्तर की भविष्यवाणी करने में इन को दर्शाता है बिंदु, जिसके बाद से यह समानांतर जाने के लिए सार्थक (लागत / प्रभाव, दक्षता भावना में) हो सकता है।
pSO + pTO

यहां छवि विवरण दर्ज करें

फिर भी,
वह यह है कि नहीं हमारे मुख्य समस्या यहाँ
यह आगे आता है:

इसके बाद,
कम्प्यूटेशनल लागतों को देखते हुए SpectralClustering(), जो कि रेडियल बोल्ट्जमैन फंक्शन कर्नेल का उपयोग करने के लिए यहां जा रहा है, किसी भी संख्या में असमान कार्य-इकाइयों के ~ exp( -gamma * distance( data, data )**2 )विभाजन से कोई अग्रिम नहीं प्रतीत होता है data, जैसे कि distance( data, data )-component, परिभाषा के अनुसार, लेकिन सभी कारणों को देखें data(रेफरी। किसी भी मूल्य-पास-संचारित { process | node }टोपोलॉजी की संचार लागत , स्पष्ट कारणों के लिए, भयानक रूप से खराब है यदि नहीं, तो खराब-उपयोग किए गए { process | node }प्रसंस्करण के लिए सबसे खराब मामले नहीं हैं, अगर सीधे विरोधी पैटर्न नहीं हैं। (कुछ वास्तव में आर्कन, मेमोरी-कम / राज्य-कम, अभी तक कंप्यूटिंग कपड़ों के अलावा)।

पंडित विश्लेषकों के लिए, हाँ - इसमें जोड़ें (और हम पहले से ही एक खराब स्थिति कह सकते हैं ) की लागत - फिर से - किसी भी-से- के-मतलब -प्रोसेसिंग, यहाँ O( N^( 1 + 5 * 5 ) )उस के बारे में N ~ len( data ) ~ 1.12E6+, कुछ के लिए हमारी इच्छा के खिलाफ भयानक रूप से जाता है स्मार्ट और तेजी से प्रसंस्करण।

तो क्या?

हालांकि सेटअप लागतों की उपेक्षा नहीं की जाती है, बढ़ी हुई संचार लागत लगभग किसी भी सुधार को सुनिश्चित करने के लिए उपरोक्त स्केच किए गए प्रयासों का उपयोग शुद्ध- [SERIAL]प्रक्रिया प्रवाह से किसी न किसी रूप में करने के लिए करती है - [CONCURRENT]या [PARALLEL]कुछ-कार्य-उप-इकाइयों का सच्चा -आर्केस्ट्रा। , किसी भी मूल्य-पास टोपोलॉजी को लागू करने के लिए (एक अग्रानुक्रम जोड़ी) को लागू करने के लिए आवश्यक ओवरहेड्स से संबंधित होने के कारण ।

अगर यह उन्हें नहीं था?

खैर, यह एक कम्प्यूटिंग साइंस ऑक्सीमोरन के रूप में लगता है - भले ही यह संभव हो, किसी भी-से-पूर्व-गणना की गई दूरी की [TIME]लागतें (जो उन अपार- जटिल जटिलता लागतों को "पहले से" ले जाएगा) (कहां-कैसे?) कोई है अन्य, अन-टालने योग्य विलंबता, एक पूर्ण-भविष्य के किसी भी-से-किसी भी दूरी मैट्रिक्स के कुछ (अज्ञात अब तक) वृद्धिशील निर्माण द्वारा संभव विलंबता की अनुमति देते हुए) लेकिन इन मुख्य रूप से वर्तमान में कुछ अन्य स्थान के लिए लागत का पुनर्संस्थापन करेगा? [TIME]- और [SPACE]महिलाएं, उन्हें कम न करें।

प्रश्न : "क्या वे कोई बेहतर विकल्प हैं? "

केवल एक, मैं अभी तक अवगत हूं, कोशिश करने के लिए है, अगर समस्या को दूसरे में फिर से तैयार करना संभव है, एक क्यूबो-तैयार, समस्या फैशन (रेफरी: क्यू uantum- यू nconstrained- बी inary- हे ptimisation , अच्छी खबर यह है कि ऐसा करने के लिए उपकरण, प्रथम-हाथ ज्ञान और व्यावहारिक समस्या को सुलझाने के अनुभव का एक आधार मौजूद है और बड़ा हो रहा है)

प्रश्न : प्रदर्शन के संदर्भ में वे प्रदान किए गए समाधानों की तुलना कैसे करते हैं ?

प्रदर्शन में दम है - QUBO- तैयार की गई समस्या O(1)में निरंतर समय ( [TIME]-Domain) में एक आशाजनक (!) सॉल्वर है और कुछ हद तक प्रतिबंधित [SPACE]-Domain (जहां हाल ही में घोषित LLNL ट्रिक्स इस भौतिक दुनिया से बचने में मदद कर सकते हैं, वर्तमान PPU कार्यान्वयन, समस्या की बाधा आकार)।


यह एक दिलचस्प जवाब है, लेकिन यह बात याद आती है - ओपी कई छोटे मॉडल को प्रशिक्षित करता है, एक भी नहीं। इसलिए आपका मूल अवलोकन ज्यादातर अप्रासंगिक है।
user10938362

@ user10938362 आपकी दावा की गई संपत्ति ( छोटे मॉडलों को प्रशिक्षित करना ) प्रसंस्करण लागतों के बड़े-ओ-मीट्रिक से ऊपर के अलावा किसी और पर कैसे अनुवाद करती है? निश्चित रूप से कई छोटे मॉडल सैद्धांतिक रूप से सिर्फ रैखिक रूप से बढ़ती हुई राशि का वादा करते हैं (अभी भी) व्यक्ति की बड़ी-ओ लागत (अब एन में छोटा है, लेकिन अन्य कारकों में नहीं) प्रसंस्करण, फिर भी, आपको इसे सभी के लिए एक और अधिक महंगा योग जोड़ना होगा सेटअप- और समाप्ति-ओवरहेड दोनों लागतों की अतिरिक्त लागतों पर सभी ऐड-ऑन संचार-ओवरहेड लागतों (params / डेटा / परिणाम + आमतौर पर प्रत्येक चरण में SER / DES प्रसंस्करण लागतों के जोड़े)
user3666197

0

यह एक उत्तर नहीं है, लेकिन ...

अगर तुम दौड़ते हो

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

(यानी, पंडों के साथ अकेले), आप देखेंगे कि आप पहले से ही कई कोर का उपयोग कर रहे हैं। ऐसा इसलिए है क्योंकि डिफ़ॉल्ट रूप से काम को समानांतर करने के लिए sklearnउपयोग करता joblibहै। आप शेड्यूलर को Dask के पक्ष में स्वैप कर सकते हैं और संभवत: थ्रेड्स के बीच डेटा साझा करने पर अधिक दक्षता प्राप्त कर सकते हैं, लेकिन जब तक आप जो काम कर रहे हैं वह सीपीयू-बाउंड जैसा है, तो ऐसा कुछ भी नहीं होगा जो आप इसे गति देने के लिए कर सकते हैं।

संक्षेप में, यह एक एल्गोरिथ्म समस्या है: यह गणना करने के लिए कि विभिन्न रूपरेखाओं पर विचार करने की कोशिश करने से पहले आपको यह पता लगाना होगा कि आपको वास्तव में क्या गणना करने की आवश्यकता है।


क्या आप यह समझा सकते हैं कि आप "... थ्रेड्स के बीच डेटा साझा करने" का उल्लेख क्यों करते हैं ... एक बार कार्य-विभाजन को joblib-spawned प्रक्रियाओं द्वारा व्यवस्थित किया गया था , जिसका थ्रेड्स के साथ कोई लेना-देना नहीं है, साझाकरण के साथ कम? तर्कों के अपने तरह के स्पष्टीकरण के लिए धन्यवाद।
user3666197

वास्तव में, jboblib आमतौर पर प्रक्रियाओं का उपयोग करता है, लेकिन यह वैकल्पिक रूप से बैकेंड के रूप में dask का उपयोग कर सकता है, जहां आप थ्रेड्स और प्रक्रियाओं के अपने मिश्रण का चयन कर सकते हैं।
मर्दुरंत

मैं एक नौसिखिया के समानांतर कंप्यूटिंग के लिए कर रहा हूँ, लेकिन भले ही sklearn समानांतर उपयोग करता है, यह इस सेटिंग में बेकार नहीं है? मेरा मतलब है, स्केलेर द्वारा किए गए ऑपरेशन बेहद सरल हैं क्योंकि प्रत्येक क्लस्टरिंग ऑपरेशन केवल 10 बिंदुओं पर लागू होता है। फिर से, मैं यहां गलत हो सकता हूं, लेकिन मुझे लगता है कि जिस तरह से हम मूल डेटा के प्रसंस्करण चक्रों को समानांतर करते हैं, वह वास्तविक समस्या है।
कुबा_

"यह इस सेटिंग में बेकार नहीं है" - ठीक है, आप 1 के बजाय प्रदर्शन के लायक 8 सीपीयू कोर का उपयोग करते हैं
मर्डुरेंट

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()
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.