如何将函数应用于两个pandas DataFrame的行

时间:2015-11-10 17:00:19

标签: python pandas dataframe

有两个pandas DataFrame,比如相同形状的dfx, dfy和完全相同的列和行索引。我想将一个函数应用于这两个DataFrame的相应行。

换句话说,假设我们有如下函数

def fun( row_x, row_y): 
    ...# a function of the corresponding rows

index成为dfx,dfy的常用索引。我想在熊猫中计算以下列表/系列

[fun(dfx[i], dfy[i]) for i in index] (pseudo-code)

通过以下代码,我创建了一个分组的两级索引DataFrame。然后我不知道如何以正确的方式应用agg

dfxy = pd.concat({'dfx':dfx, 'dfy':dfy})
dfxy = dfxy.swaplevel(0,1,axis=0).sort_index(level=0)
grouped=dfxy.groupby(level=0)

2 个答案:

答案 0 :(得分:2)

In [19]:
dfx = pd.DataFrame(data = np.random.randint(0 , 100 , 50).reshape(10 ,-1) , columns=list('abcde'))
dfx
Out[19]:
a   b   c   d   e
3   44  8   55  95
26  5   18  34  10
20  20  91  15  8
83  7   50  47  27
97  65  10  94  93
44  6   70  60  4
38  64  8   67  92
44  21  42  6   12
30  98  34  7   79
76  7   14  58  5

In [4]:
dfy = pd.DataFrame(data = np.random.randint(0 , 100 , 50).reshape(10 ,-1) , columns=list('fghij'))
dfy
Out[4]:
f   g   h   i   j
82  48  29  54  78
7   31  78  38  30
90  91  43  8   40
52  88  13  87  39
41  88  90  51  91
55  4   94  62  98
31  23  4   59  93
87  12  33  77  0
25  99  39  23  1
7   50  46  39  66

In [13]:
dfxy = pd.concat({'dfx':dfx, 'dfy':dfy} , axis = 1)
dfxy
Out[13]:
       dfx                 dfy
a   b   c   d   e   f   g   h   i   j
20  76  5   98  38  82  48  29  54  78
39  36  9   3   74  7   31  78  38  30
43  12  50  72  14  90  91  43  8   40
89  41  95  91  86  52  88  13  87  39
33  30  55  64  94  41  88  90  51  91
89  84  48  1   60  55  4   94  62  98
68  40  27  10  63  31  23  4   59  93
33  10  86  89  67  87  12  33  77  0
56  89  0   70  67  25  99  39  23  1
48  58  98  18  24  7   50  46  39  66

def f(x , y):
    return pd.Series(data = [np.mean(x) , np.mean(y)] , index=['x_mean' , 'y_mean'])

In [17]:
dfxy.apply( lambda x : f(x['dfx'] , x['dfy']) , axis = 1)
Out[17]:
   x_mean   y_mean
0   47.4    58.2
1   32.2    36.8
2   38.2    54.4
3   80.4    55.8
4   55.2    72.2
5   56.4    62.6
6   41.6    42.0
7   57.0    41.8
8   56.4    37.4
9   49.2    41.6

答案 1 :(得分:1)

这可能是你想要的吗?

In [1]: import pandas as pd

In [2]: import numpy as np

In [3]: dfx = pd.DataFrame(data=np.random.randint(0,100,50).reshape(10,-1),
                           columns=['index', 'a', 'b', 'c', 'd'])

In [4]: dfy = pd.DataFrame(data=np.random.randint(0,100,50).reshape(10,-1),
                           columns=['index', 'a', 'b', 'c', 'd'])

In [5]: dfy['index'] = dfx['index']

In [6]: print(dfx)
   index   a   b   c   d
0     25  41  46  18  98
1      0  21   9  20  29
2     18  78  63  94  70
3     86  71  71  95  64
4     23  33  19  34  29
5     69  10  91  19  42
6     92  68  60  12  58
7     74  49  22  74   1
8     47  35  56  41  80
9     93  20  44  16  49

In [7]: print(dfy)
   index   a   b   c   d
0     25  28  35  96  89
1      0  44  94  50  43
2     18  18  39  75  45
3     86  18  87  72  88
4     23   2  28  24   4
5     69  53  55  55  40
6     92   0  52  54  91
7     74   8   1  96  59
8     47  74  21   7   7
9     93  42  83  42  60

In [8]: print(dfx.merge(dfy, on='index'))
   index  a_x  b_x  c_x  d_x  a_y  b_y  c_y  d_y
0     25   41   46   18   98   28   35   96   89
1      0   21    9   20   29   44   94   50   43
2     18   78   63   94   70   18   39   75   45
3     86   71   71   95   64   18   87   72   88
4     23   33   19   34   29    2   28   24    4
5     69   10   91   19   42   53   55   55   40
6     92   68   60   12   58    0   52   54   91
7     74   49   22   74    1    8    1   96   59
8     47   35   56   41   80   74   21    7    7
9     93   20   44   16   49   42   83   42   60

In [9]: def my_function(x):
   ...:     return sum(x)
   ...:

In [10]: print(dfx.merge(dfy, on='index').drop('index', axis=1).apply(my_function, axis=1))
0    451
1    310
2    482
3    566
4    173
5    365
6    395
7    310
8    321
9    356
dtype: int64

In [11]: print(pd.DataFrame(
         {
          'my_function':
              dfx.merge(dfy, on='index').\
              drop('index', axis=1).apply(my_function, axis=1), 
          'index':
              dfx['index']
         }))
   index  my_function
0     25          451
1      0          310
2     18          482
3     86          566
4     23          173
5     69          365
6     92          395
7     74          310
8     47          321
9     93          356