2017-09-01 5 views
15

मेरे पास सीएसवी फाइलों का एक बड़ा डेटासेट है जिसमें दो अलग-अलग ऑब्जेक्ट्स शामिल हैं: "object_a" और "object_b"। इन इकाइयों में से प्रत्येक के पास एक संख्यात्मक "टिक" मूल्य भी है।बड़े डेटा सेट के लिए आवेदन का उपयोग करके इस पांडस नौकरी को पूरा करने का तेज़ तरीका?

Type,  Parent Name, Ticks 
object_a, 4556421,  34 
object_a, 4556421,  0 
object_b, 4556421,  0 
object_a, 3217863,  2 
object_b, 3217863,  1 
...... 

प्रत्येक वस्तु के शेयरों एक "पिता का नाम" मूल्य तो ज्यादातर मामलों में, प्रत्येक वस्तु में से एक एक "पिता का नाम" मूल्य साझा करेंगे लेकिन यह हमेशा मामला नहीं है। मैं कहाँ) देखते हैं> 1 object_a के तहत एक जनक नाम

  • निकालने सभी object_a के;:

    मैं इस डेटासेट के साथ दो लक्ष्य हैं ii) object_a में 0 टिक हैं लेकिन अन्य ऑब्जेक्ट_ए में 0 टिक हैं। यानी शून्य टिक्स के साथ सिर्फ

  • सभी ऑब्जेक्ट_बी को अभिभावक नाम के नीचे निकालें जहां i) वहाँ = = object_a और; ii) object_b 0 टिक है, लेकिन object_a> 0 टिक्स

मेरा पहला दृष्टिकोण दोनों कार्यों के लिए दो अलग-अलग काम करता है, मात्रा और उत्पादन में CSV फ़ाइलों (आमतौर पर आकार में 1.5GB) है पढ़ने के लिए है

for chunk in pd.read_csv(file, chunksize=500000): 

    #objective one 
    chunk_object_a = chunk.groupby(['Parent Name']).apply(lambda g: objective_one(g.name, g)) 
    .... 
    .... 
    #objective two 
    chunk_object_b = chunk.groupby(['Parent Name']).apply(lambda g: objective_two(g.name, g)) 

# फिर dataframes कहां लिखें: उन्हें जनक नाम के अनुसार समूहीकरण के बाद एक और csv फ़ाइल के लिए निकाले पंक्तियों ...

def objective_one(group_name, group_df): 

    group_df = group_df[group_df['Type'] == 'object_a'] 

    if len(group_df) > 1: 

     zero_tick_object_a = group_df[group_df['Ticks'] == 0] 

     if len(zero_click_object_a) < len(group_df): 

      return zero_click_object_a 

     else: 

      return pd.DataFrame(columns=group_df.columns) 
    else: 

     return pd.DataFrame(columns=group_df.columns) 



def objective_two(group_name, group_df): 

    object_a_in_group_df = group_df[group_df['Type'] == 'object_a'] 
    object_b_has_no_clicks_in_group_df = group_df[(group_df['Type'] == 'object_b') & (group_df['Ticks'] == 0)] 

    if len(object_a_in_group_df) >= 1 and len(object_b_has_no_ticks_in_group_df) >= 1: 

     has_ticks_objects = objects_in_group_df[object_a_in_group_df['Ticks'] >= 1] 

     if len(has_ticks_object_a) > 0: 

      return object_B_has_no_ticks_in_group_df 

     else: 

      return pd.DataFrame(columns=group_df.columns) 
    else: 

     return pd.DataFrame(columns=group_df.columns) 

यहाँ मुख्य विधि में इन कार्यों के लिए कॉल कर रहे हैं एक सीएसवी फ़ाइल के लिए लागू विधियों द्वारा tputted

इस दृष्टिकोण के साथ समस्या यह है कि जब मुझे यह आउटपुट मिलता है, तो यह 1 जीबी और ऊपर की सीमा में बड़ी फ़ाइलों में बहुत धीमी है। एक और मुद्दा यह है कि सीएसवी से हिस्सों में इसे पढ़ने से कुछ समूहों को प्रभावी रूप से आधे में काट दिया जा सकता है (यानी एक अभिभावक नाम को एक खंड में विभाजित किया जा सकता है और अगला, निकाली गई वस्तुओं की गलत संख्या के लिए)

क्या कोई तरीका है इसे किसी भी तेज़ बनाने के लिए अनुकूलित करें और साथ ही, मेरी चंक समस्या के आसपास हो जाओ?

+0

के लिए परिणाम प्राप्त करें यह आप अगले लेकिन नहीं कैसे करना है जा रहे हैं की बात होगी सीएसवी बनाया जाना है – yukclam9

+0

फ़ंक्शन घोषणा से पहले '@ numba.jit' जोड़ने का प्रयास करें। यह इस फ़ंक्शन को बाइट कोड में संकलित करेगा। – ADR

उत्तर

3

समस्या पर मेरे शॉट:

  • निकालने सभी object_a के तहत एक जनक नाम के जहां i) वहाँ> 1 object_a है और कर रहे हैं; ii) object_a में 0 टिक हैं लेकिन अन्य object_a में> 0 टिक हैं। यानी शून्य टिक्स के साथ सिर्फ
  • सभी ऑब्जेक्ट_बी को अभिभावक नाम के नीचे निकालें जहां i) वहाँ = = object_a और; ii) object_b 0 टिक है, लेकिन object_a> 0 टिक्स

मेरी पहली छाप जब यह पढ़ है कि वास्तविक "प्रकार" वास्तव में बात नहीं करता है, हम बस चाहते हैं एक> के साथ मौजूदा object_a 0 प्रत्येक समूह के लिए टिकटें, और उनके तत्वों के बावजूद 0 तत्वों के साथ सभी तत्व निकालें।

यह ध्यान में रखते हुए, मेरा दृष्टिकोण किसी भी माता-पिता के लिए object_a टिकों की संख्या को गिनने के लिए एक नया कॉलम बनाने वाला था। यदि यह संख्या> 0 है, तो इसका मतलब है कि कम से कम 1 object_a टिक> 0 के साथ मौजूद है।

In [63]: df.groupby(['Parent Name']).apply(lambda x: x[x['Type'] == 'object_a']['Ticks'].sum()) 
Out[63]: 
Parent Name 
3217863  2 
4556421 34 
dtype: int64 

चलो अब विलय कि मूल DataFrame में करते हैं ...

In [64]: sumATicks = df.groupby(['Parent Name']).apply(lambda x: x[x['Type'] == 'object_a']['Ticks'].sum()) 

In [65]: merged = df.merge(pd.DataFrame(sumATicks).rename(columns={0: 'nbATicks'}), left_on='Parent Name', right_index=True) 

In [66]: merged 
Out[66]: 
     Type Parent Name Ticks nbATicks 
0 object_a  4556421  34  34 
1 object_a  4556421  0  34 
2 object_b  4556421  0  34 
3 object_a  3217863  2   2 
4 object_b  3217863  1   2 

... और सभी दिलचस्प पंक्तियां निकालने, मापदंड मैं ऊपर कहा गया है के अनुसार:

In [67]: merged[(merged['nbATicks'] > 0) & (merged['Ticks'] == 0)] 
Out[67]: 
     Type Parent Name Ticks nbATicks 
1 object_a  4556421  0  34 
2 object_b  4556421  0  34 

उम्मीद है कि मैं किसी भी फ्रिज मामले को नहीं भूल गया ...

खंड की समस्या के बारे में, आप बस लोड क्यों नहीं करते स्मृति में पूरी सीएसवी फ़ाइल? यदि यह है जो बड़ा है, तो आप प्रसंस्करण से पहले पेरेंटनाम द्वारा क्रमबद्ध करने और प्रासंगिक स्थानों पर हिस्सों को विभाजित करने का प्रयास कर सकते हैं।

1

यहाँ समस्या के लिए मेरा विचार आता है:

मुझे लगता है कि पहला उद्देश्य आसान है क्योंकि हम केवल object_a साथ पंक्तियों पर निर्भर हैं। हम बूलियन सूची में स्थिति परिवर्तित करने के लिए उपयोग कर सकते हैं बदलने: दूसरा उद्देश्य मैं object_a के लिए आवश्यकताओं को पूरा करने Parent_Names की एक सूची बना लिए

df_1 = df.loc[df['Type']=='object_a'] 
object_a = df_1.loc[(df_1.groupby('Parent_Name')['Ticks'].transform(min)==0)& 
        (df_1.groupby('Parent_Name')['Ticks'].transform(max)>0)& 
        (a['Ticks']==0) 
        ] 
Out[1]: 
     Type Parent_Name Ticks 
1 object_a  4556421  0 

। अगले चरण में isin केवल संबंधित पंक्तियों का चयन करने के लिए प्रयोग किया जाता है।

a_condition = df.loc[df['Type']=='object_a'].groupby('Parent_Name').sum() 
a_condition = a_condition[a_condition>0].index 

object_b = df.loc[(df['Type']=='object_b')& 
        (df['Ticks']==0)& 
        (df['Parent_Name'].isin(a_condition)) 
       ] 
Out[2]: 
     Type Parent_Name Ticks 
2 object_b  4556421  0 
1
In [35]: df 
Out[32]: 
     Type   Parent Name Ticks 
0 object_a    4556421  34 
1 object_a    4556421  0 
2 object_b    4556421  0 
3 object_a    3217863  2 
4 object_b    3217863  1 

सकल tuple रों

In [33]: df1 = df.groupby(['Parent Name', 
          'Type']).agg(lambda x: tuple(x)).unstack(1) 

In [34]: df1 
Out[34]: 
         Ticks   
Type    object_a object_b 
     Parent Name     
3217863    (2,)  (1,) 
4556421    (34, 0)  (0,) 

में डेटा अपने मामले # के लिए बूलियन मुखौटा निर्माण 1

In [35]: mask1 = df1.apply(lambda x: (len(x[0])>1) & ((x[0]).count(0)==1), 
          axis=1) 

In [36]: mask1 
Out[36]: 
     Parent Name 
3217863 False 
4556421  True 
dtype: bool 

अपने मामले # के लिए बूलियन मुखौटा निर्माण 2

In [37]: mask2 = df1.apply(lambda x: ((len(x[0])>=1) & 
             (len(set(x[0]).difference([0]))>0) & 
             (len(x[1])==1) & 
             (x[1][0]==0)), 
          axis=1) 

In [38]: mask2 
Out[38]: 
     Parent Name 
3217863 False 
4556421  True 
dtype: bool 

मामले # 1

In [39]: df1.loc[mask1, [('Ticks', 'object_a')]] 
Out[39]: 
         Ticks 
Type    object_a 
     Parent Name   
4556421    (34, 0) 

के लिए परिणाम हासिल दक्षता के मामले में मामला # 2

In [30]: df1.loc[mask2, [('Ticks', 'object_b')]] 
Out[30]: 
         Ticks 
Type    object_b 
     Parent Name   
4556421    (0,) 
संबंधित मुद्दे

 संबंधित मुद्दे