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

3

示例

假设base_df是下面展示的小型数据框:

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

请注意,base_df 的行有两级多重索引。(这里的问题之一是在派生数据帧中“传播”这个多重索引的值。)
现在,函数 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

概念上,所需的数据框是通过为base_df的每一行生成一个“子数据框”,然后垂直连接这些子数据框来获得的。与每行对应的子数据框具有3级多重索引。该多重索引的前两个级别(IS)来自该行的base_df的多重索引值,而其最后一级别(key),以及(唯一的)F列的值来自由fn返回的数据框,用于该行的seed值。
我不太清楚如何将行的原始多重索引值传播到由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的定义。就这个问题而言,它的内部不重要。重要的是它需要一个整数seed作为参数,并返回一个数据框,如前所述。

import numpy
def fn(seed, _spec='{{0:0{0:d}b}}'.format(5)):
    numpy.random.seed(int(seed))
    n = numpy.random.randint(2, 5)
    r = numpy.random.rand(n)
    k = map(_spec.format, numpy.random.randint(0, 31, size=n))
    result = pandas.DataFrame(r, columns=['F'], index=k)
    result.index.name = 'key'
    return result

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

1个回答

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

Option 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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接