函数式编程:如何为包含多索引列的数据框创建新列?

Functional Programming: How does one create a new column to a dataframe that contains a multiindex column?

假设下面的简化数据框。 (实际的 df 大得多。)如何将值分配给新列 f,使得 f 是另一列的函数(例如,e) ?我很确定需要使用 applymap 但从未使用具有多索引列的数据框来完成此操作?

df = pd.DataFrame([[1,2,3,4], [5,6,7,8], [9,10,11,12], [13,14,15,16]])
df.columns = pd.MultiIndex.from_tuples((("a", "d"), ("a", "e"), ("b", "d"), ("b","e")))
df
    a       b
    d   e   d   e
0   1   2   3   4
1   5   6   7   8
2   9  10  11  12
3  13  14  15  16

期望的输出:

    a          b
    d   e   f  d   e   f
0   1   2   1  3   4   1
1   5   6   1  7   8  -1
2   9  10  -1  11  12 -1
3  13  14  -1  15  16 -1

希望能够应用以下行并将它们分配给新列 f。两个问题:首先,包含 apply 的最后一行不起作用,但希望我的意图很明确。其次,我不确定如何将值分配给具有多索引列结构的数据框的新列。希望能够使用函数式编程方法。

lt = df.loc(axis=1)[:,'e'] < 8
gt = df.loc(axis=1)[:,'e'] >= 8
conditions = [lt, gt]
choices = [1, -1]
df.loc(axis=1)[:,'f'] = df.loc(axis=1)[:,'e'].apply(np.select(conditions, choices))
nms = [(i, 'f')for i, j in df.columns if j == 'e']    
df[nms] = (df.iloc[:, [j == 'e' for i, j in df.columns]] < 8) * 2 - 1

df = df.sort_index(axis=1)
df
 a          b       
    d   e  f   d   e  f
0   1   2  1   3   4  1
1   5   6  1   7   8 -1
2   9  10 -1  11  12 -1
3  13  14 -1  15  16 -1

编辑:

自定义订购:

d = {i:j for j, i in enumerate(df.columns.levels[0])}
df1 = df.loc[:, sorted(df.columns, key = lambda x: d[x[0]])]

如果整个数据在某种程度上是对称的,你可以这样做:

df.stack(0).assign(f = lambda x: 2*(x.e < 8) - 1).stack().unstack([1,2])
Out[]: 
    a          b       
    d   e  f   d   e  f
0   1   2  1   3   4  1
1   5   6  1   7   8 -1
2   9  10 -1  11  12 -1
3  13  14 -1  15  16 -1