2014-05-15 478 views
15

我有一個timeindex和包含三維向量的座標3列一數據幀:熊貓申請函數返回多個值的行中大熊貓數據幀

      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) 

我結束ü p與元素爲元組的Pandas系列。這是因爲應用程序將取消myfunc的結果而不解壓縮它。我如何更改myfunc以便獲得具有3列的新df?

編輯:

下面工作的所有解決方案。 Series解決方案允許使用列名,List解決方案似乎執行得更快。

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它會將它們放在DataFrame中。

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

這有獎金,你可以給每個結果列的標籤。如果你返回一個DataFrame,它只需爲該組插入多行。

+0

在[靈活應用]中查看更多示例(http://pandas-docs.github.io/pandas-docs-travis/groupby.html#flexible-apply) –

+1

該系列答案似乎是規範的答案。但是,在0.18.1版本上,該系列解決方案需要比運行多次的時間長4倍。 –

2

發現了一個可能的解決方案,通過改變MYFUNC返回一個像這樣的np.array:

import numpy as np 

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

任何更好的解決方案?

5

基於卓越answer通過@ U2EF1,我已經創建了一個應用指定的函數返回元組到數據幀領域,並擴展結果返回給數據幀一個方便的功能。

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 

希望它可以幫助別人。