2014-05-15 12 views
15

मैं एक timeindex और 3 एक 3 डी वेक्टर के निर्देशांक युक्त कॉलम के साथ एक dataframe है लागू होते हैं:पांडा समारोह है कि पांडा dataframe में पंक्तियों को एक से अधिक मान देता है

      x    y    z 
ts 
2014-05-15 10:38   0.120117  0.987305  0.116211 
2014-05-15 10:39   0.117188  0.984375  0.122070 
2014-05-15 10:40   0.119141  0.987305  0.119141 
2014-05-15 10:41   0.116211  0.984375  0.120117 
2014-05-15 10:42   0.119141  0.983398  0.118164 

मैं प्रत्येक पंक्ति के लिए एक परिवर्तन लागू करना चाहते हैं वह भी एक वेक्टर रिटर्न

def myfunc(a, b, c): 
    do something 
    return e, f, g 

लेकिन अगर मैं ऐसा: मैं यू अंत

df.apply(myfunc, axis=1) 

एक पांडस श्रृंखला के साथ पी जिसका तत्व tuples हैं। यह बीकॉज लागू होगा बिना इसे अनपॅक किए Myfunc का परिणाम लेगा। मैं myfunc कैसे बदल सकता हूं ताकि मैं 3 कॉलम के साथ एक नया डीएफ प्राप्त कर सकूं?

संपादित करें:

काम ठीक नीचे स्थित सभी समाधान। श्रृंखला समाधान कॉलम नामों की अनुमति देता है, सूची समाधान तेजी से निष्पादित प्रतीत होता है।

def myfunc1(args): 
    e=args[0] + 2*args[1] 
    f=args[1]*args[2] +1 
    g=args[2] + args[0] * args[1] 
    return pd.Series([e,f,g], index=['a', 'b', 'c']) 

def myfunc2(args): 
    e=args[0] + 2*args[1] 
    f=args[1]*args[2] +1 
    g=args[2] + args[0] * args[1] 
    return [e,f,g] 

%timeit df.apply(myfunc1 ,axis=1) 

100 loops, best of 3: 4.51 ms per loop 

%timeit df.apply(myfunc2 ,axis=1) 

100 loops, best of 3: 2.75 ms per loop 

उत्तर

4

बस टुपल की बजाय एक सूची वापस करें।

In [81]: df 
Out[81]: 
          x   y   z 
ts            
2014-05-15 10:38:00 0.120117 0.987305 0.116211 
2014-05-15 10:39:00 0.117188 0.984375 0.122070 
2014-05-15 10:40:00 0.119141 0.987305 0.119141 
2014-05-15 10:41:00 0.116211 0.984375 0.120117 
2014-05-15 10:42:00 0.119141 0.983398 0.118164 

[5 rows x 3 columns] 

In [82]: def myfunc(args): 
    ....:  e=args[0] + 2*args[1] 
    ....:  f=args[1]*args[2] +1 
    ....:  g=args[2] + args[0] * args[1] 
    ....:  return [e,f,g] 
    ....: 

In [83]: df.apply(myfunc ,axis=1) 
Out[83]: 
          x   y   z 
ts            
2014-05-15 10:38:00 2.094727 1.114736 0.234803 
2014-05-15 10:39:00 2.085938 1.120163 0.237427 
2014-05-15 10:40:00 2.093751 1.117629 0.236770 
2014-05-15 10:41:00 2.084961 1.118240 0.234512 
2014-05-15 10:42:00 2.085937 1.116202 0.235327 
+3

यह काम नहीं करता है। यह एक श्रृंखला लौटाता है जिसका तत्व सूचियां हैं। मैं पांडा 0.18.1 पर हूँ –

18

रिटर्न Series और यह उन्हें डेटाफ्रेम में रखेगा।

def myfunc(a, b, c): 
    do something 
    return pd.Series([e, f, g]) 

यह बोनस है कि आप प्रत्येक परिणामी कॉलम को लेबल दे सकते हैं। यदि आप डेटाफ्रेम वापस करते हैं तो यह समूह के लिए कई पंक्तियों को सम्मिलित करता है।

+0

[लचीली लागू] (http://pandas-docs.github.io/pandas-docs-travis/groupby.html#flexible-apply) पर अधिक उदाहरण देखें –

+1

श्रृंखला का उत्तर कैनोलिकल लगता है। हालांकि, संस्करण 0.18.1 पर श्रृंखला समाधान को कई बार लागू होने से लगभग 4x लंबा लगता है। –

2

मिले एक संभव समाधान, myfunc बदलते इस तरह एक np.array वापस जाने के लिए द्वारा:

import numpy as np 

def myfunc(a, b, c): 
    do something 
    return np.array((e, f, g)) 

किसी भी बेहतर समाधान?

5

उत्कृष्ट answer @ U2EF1 द्वारा आधार पर, मैं एक निर्दिष्ट समारोह है कि एक dataframe क्षेत्र के लिए tuples रिटर्न पर लागू होता है, और परिणाम वापस dataframe जो विस्तृत होने पर एक आसान समारोह बना लिया है।

def apply_and_concat(dataframe, field, func, column_names): 
    return pd.concat((
     dataframe, 
     dataframe[field].apply(
      lambda cell: pd.Series(func(cell), index=column_names))), axis=1) 

उपयोग:

df = pd.DataFrame([1, 2, 3], index=['a', 'b', 'c'], columns=['A']) 
print df 
    A 
a 1 
b 2 
c 3 

def func(x): 
    return x*x, x*x*x 

print apply_and_concat(df, 'A', func, ['x^2', 'x^3']) 

    A x^2 x^3 
a 1 1 1 
b 2 4 8 
c 3 9 27 

आशा है कि यह किसी को मदद मिलती है।

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