示例
假设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级多重索引。该多重索引的前两个级别(I
和S
)来自该行的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之间的一些整数的二进制表示,但这个事实在问题中没有任何作用。