2013-10-26 11 views
9

में lazy_evaluated डेटा फ्रेम कॉलम बनाने के लिए कैसे करें, मूल डेटा रखने के लिए मेरे पास एक बड़ा डेटाफ्रेम df है, और बुनियादी डेटा कॉलम द्वारा गणना किए गए व्युत्पन्न डेटा को पकड़ने के लिए कई और कॉलम बनाने की आवश्यकता है।पांडस

मैं ऐसा कर सकते हैं की तरह पांडा में:

df['derivative_col1'] = df['basic_col1'] + df['basic_col2'] 
df['derivative_col2'] = df['basic_col1'] * df['basic_col2'] 
.... 
df['derivative_coln'] = func(list_of_basic_cols) 

आदि पांडा की गणना करने और सभी को एक बार सभी व्युत्पन्न स्तंभों के लिए स्मृति आवंटित करेगा।

अब मुझे क्या चाहिए कि आभासी कॉलम की गणना और स्मृति आवंटन को वास्तविक आवश्यकता पल में स्थगित करने के लिए आलसी मूल्यांकन तंत्र होना है। कुछ हद तक के रूप में lazy_eval_columns को परिभाषित: यह अजगर 'उपज' जनरेटर की तरह समय/स्मृति की बचत होगी

df['derivative_col1'] = pandas.lazy_eval(df['basic_col1'] + df['basic_col2']) 
df['derivative_col2'] = pandas.lazy_eval(df['basic_col1'] * df['basic_col2']) 

, के लिए अगर मैं df['derivative_col2'] आदेश जारी केवल विशिष्ट गणना और स्मृति आवंटन triger।

तो पांडों में lazy_eval() कैसे करें? किसी भी टिप/विचार/रेफरी स्वागत है।

+0

महान प्रश्न। पता नहीं है कि पांडा की ऐसी चीज है, यद्यपि। विचार मुझे दृश्यों में एसक्यूएल गणना कॉलम याद दिलाता है। –

उत्तर

8

0.13 में शुरू हो रहा है (बहुत जल्द रिलीज हो रहा है), आप ऐसा कुछ कर सकते हैं। यह एक गतिशील सूत्र का मूल्यांकन करने के लिए जेनरेटर का उपयोग कर रहा है। इन-लाइन eval के माध्यम से काम 0.13 में एक अतिरिक्त सुविधा होगी, देख here

In [19]: df = DataFrame(randn(5, 2), columns=['a', 'b']) 

In [20]: df 
Out[20]: 
      a   b 
0 -1.949107 -0.763762 
1 -0.382173 -0.970349 
2 0.202116 0.094344 
3 -1.225579 -0.447545 
4 1.739508 -0.400829 

In [21]: formulas = [ ('c','a+b'), ('d', 'a*c')] 

एक जनरेटर है कि एक सूत्र eval का उपयोग कर मूल्यांकन करता बनाएं; परिणाम असाइन करता है, फिर परिणाम उत्पन्न करता है।

In [22]: def lazy(x, formulas): 
    ....:  for col, f in formulas: 
    ....:   x[col] = x.eval(f) 
    ....:   yield x 
    ....:   

कार्रवाई

In [23]: gen = lazy(df,formulas) 

In [24]: gen.next() 
Out[24]: 
      a   b   c 
0 -1.949107 -0.763762 -2.712869 
1 -0.382173 -0.970349 -1.352522 
2 0.202116 0.094344 0.296459 
3 -1.225579 -0.447545 -1.673123 
4 1.739508 -0.400829 1.338679 

In [25]: gen.next() 
Out[25]: 
      a   b   c   d 
0 -1.949107 -0.763762 -2.712869 5.287670 
1 -0.382173 -0.970349 -1.352522 0.516897 
2 0.202116 0.094344 0.296459 0.059919 
3 -1.225579 -0.447545 -1.673123 2.050545 
4 1.739508 -0.400829 1.338679 2.328644 

में तो उपयोगकर्ता मूल्यांकन (और ऑन-डिमांड) के लिए आदेश देने निर्धारित। सिद्धांत में numba इसका समर्थन करने जा रहा है, इसलिए पांडा संभवतः eval (जो वर्तमान में तत्काल मूल्यांकन के लिए numexpr का उपयोग करता है) के लिए बैकएंड के रूप में इसका समर्थन करता है।

मेरा 2 सी।

आलसी मूल्यांकन अच्छा है, लेकिन पाइथन की अपनी निरंतरता/उत्पन्न सुविधाओं का उपयोग करके आसानी से प्राप्त किया जा सकता है, इसलिए इसे संभवतः पांडा में बनाकर, काफी मुश्किल है, और आम तौर पर उपयोगी होने के लिए वास्तव में एक अच्छा उपयोग करने की आवश्यकता होगी।

+0

आने वाले अद्यतन cersion में 'फॉर्मूला' और eval सुविधा होना अच्छा लगता है। और मैं ऑन-डिमांड गणना को ट्रिगर करने के लिए df ['lazy_eval_col_x'] वाक्यविन्यास का उपयोग करने के तरीके के बारे में और जानना चाहता हूं। – bigbug

5

आप DataFrame उपclass कर सकते हैं, और कॉलम को property के रूप में जोड़ सकते हैं। उदाहरण के लिए,

import pandas as pd 

class LazyFrame(pd.DataFrame): 
    @property 
    def derivative_col1(self): 
     self['derivative_col1'] = result = self['basic_col1'] + self['basic_col2'] 
     return result 

x = LazyFrame({'basic_col1':[1,2,3], 
       'basic_col2':[4,5,6]}) 
print(x) 
# basic_col1 basic_col2 
# 0   1   4 
# 1   2   5 
# 2   3   6 

संपत्ति को एक्सेस करना (x.derivative_col1 के माध्यम से, नीचे) derivative_col1 समारोह LazyFrame में परिभाषित कहता है।इस समारोह परिणाम की गणना करता है और LazyFrame उदाहरण के लिए ली गई कॉलम जोड़ने पर:

print(x.derivative_col1) 
# 0 5 
# 1 7 
# 2 9 

print(x) 
# basic_col1 basic_col2 derivative_col1 
# 0   1   4    5 
# 1   2   5    7 
# 2   3   6    9 

ध्यान दें कि आप एक बुनियादी स्तंभ को संशोधित करता है, तो:

x['basic_col1'] *= 10 

व्युत्पन्न स्तंभ नहीं स्वचालित रूप से अपडेट है:

print(x['derivative_col1']) 
# 0 5 
# 1 7 
# 2 9 

लेकिन यदि आप संपत्ति तक पहुंचते हैं, तो मानों को फिर से नियंत्रित किया जाता है:

print(x.derivative_col1) 
# 0 14 
# 1 25 
# 2 36 

print(x) 
# basic_col1 basic_col2 derivative_col1 
# 0   10   4    14 
# 1   20   5    25 
# 2   30   6    36