将数据帧返回函数应用于基础数据帧的每一行

时间:2017-07-01 21:31:16

标签: python pandas group-by apply pandas-groupby

玩具示例

假设base_df是如下所示的微小数据框:

In [221]: base_df
Out[221]: 
     seed
I S      
0 a     0
  b     1
1 a     2
  b     3

请注意base_df为行提供了2级多索引。 (这里的部分问题涉及"在派生数据帧中传播"这个多索引的值。)

现在,函数fn(在本文末尾给出的定义)将整数seed作为参数,并返回由字符串键 1 。例如:

In [222]: fn(0)
Out[222]: 
              F
key            
01011  0.592845
10100  0.844266

In [223]: fn(1)
Out[223]: 
              F
key            
11110  0.997185
01000  0.932557
11100  0.128124

我想生成一个新的数据帧,实质上是将fn应用于base_df的每一行,并垂直连接结果数据帧。更具体地说,期望的结果如下所示:

                  F
I S key            
0 a 01011  0.592845
    10100  0.844266
  b 11110  0.997185
    01000  0.932557
    11100  0.128124
1 a 01101  0.185082
    01110  0.931541
  b 00100  0.070725
    11011  0.839949
    11111  0.121329
    11000  0.569311

IOW,从概念上讲,通过生成一个"子数据帧"来获得所需的数据帧。对于base_df的每一行,并垂直连接这些子数据帧。对应于每行的子数据帧具有3级多索引。此多索引的前两个级别(IS)来自base_df该行的多索引值,而其最后一级({{1} }}),以及(孤独)key列的值来自F为该行fn值返回的数据框。

我不清楚的部分是如何将行的原始多索引值传播到由seed为该行创建的数据行的行{{{1} 1}}值。

重要提示:我正在寻找一种与fn多指数级别的名称无关的方法和他们的号码。

我尝试了以下

seed

...但评估失败,错误

base_df

有没有方便的方法来做我想做的事情?

以下是base_df.apply(lambda row: fn(row.seed), axis=1) 的定义。就这个问题而言,它的内部结构并不重要。重要的是它需要一个整数ValueError: Shape of passed values is (4, 2), indices imply (4, 1) 作为参数,并返回一个数据帧,如前所述。

fn

1 在这个例子中,这些键恰好对应于0到31之间的某个整数的二进制表示,包括在内,但这个事实在这个问题中没有任何作用。

1 个答案:

答案 0 :(得分:5)

选项1
groupby

base_df.groupby(level=[0, 1]).apply(fn)

                  F
I S key            
0 a 11010  0.385245
    00010  0.890244
    00101  0.040484
  b 01001  0.569204
    11011  0.802265
    00100  0.063107
1 a 00100  0.947827
    00100  0.056551
    11000  0.084872
  b 11110  0.592641
    00110  0.130423
    11101  0.915945

选项2
pd.concat

pd.concat({t.Index: fn(t.seed) for t in base_df.itertuples()})

                  F
    key            
0 a 11011  0.592845
    00011  0.844266
  b 00101  0.997185
    01111  0.932557
    00000  0.128124
1 a 01011  0.185082
    10010  0.931541
  b 10011  0.070725
    01010  0.839949
    01011  0.121329
    11001  0.569311