将条件列添加到熊猫的多索引数据框中

Adding a conditional column to a panda's multiindex dataframe

我有以下多索引数据框,正在努力向数据框添加条件列。我当前的代码生成错误:

ValueError: Wrong number of items passed 4, placement implies 1 

数据框如下:

       ed12 comdty              xau curncy             
           PX_LAST MOV_AVG_200D    PX_LAST MOV_AVG_200D
date                                                       
1997-10-06       93.75      93.2863     332.55       339.45
1997-10-07       93.78      93.2881     331.45       339.27
1997-10-08       93.65      93.2892     333.25       339.09
1997-10-09       93.64      93.2904     327.75       338.90
1997-10-10       93.59      93.2913     329.65       338.74

我正在尝试为每个名为 "BREADTH" 的 ed12 comdty 和 xau curncy 索引添加第三列,它是 1 还是 0,具体取决于该索引的 PX_LAST 列是 > = MOV_AVG_200D.

代码如下:

for ticker in data.columns.levels[0]:

data[(ticker,'BREADTH')] = data.where(data[(ticker,'PX_LAST')]>=data[(ticker,'MOV_AVG_200D')],1,0)

谢谢!

最简单的方法是通过 astype:

将布尔掩码转换为 int
import pandas as pd

for ticker in data.columns.levels[0]:
    mask = data[(ticker,'PX_LAST')]>=data[(ticker,'MOV_AVG_200D')]
    data[(ticker,'BREADTH')] = mask.astype(int)

data = data.sort_index(axis=1,ascending=[True, False])
print (data)
           ed12 comdty                      xau curncy                     
               PX_LAST MOV_AVG_200D BREADTH    PX_LAST MOV_AVG_200D BREADTH
date                                                                       
1997-10-06       93.75      93.2863       1     332.55       339.45       0
1997-10-07       93.78      93.2881       1     331.45       339.27       0
1997-10-08       93.65      93.2892       1     333.25       339.09       0
1997-10-09       93.64      93.2904       1     327.75       338.90       0
1997-10-10       93.59      93.2913       1     329.65       338.74       0

或使用 stack 进行整形,添加带有布尔掩码 astype 的列,然后按 [=16= 重新整形]swaplevel + sort_index:

data = data.stack(level=0)
data['BREADTH'] = (data['PX_LAST'] >= data['MOV_AVG_200D']).astype(int)
data = data.unstack().swaplevel(0,1,axis=1).sort_index(axis=1, ascending=[True, False])
print (data)
           ed12 comdty                      xau curncy                     
               PX_LAST MOV_AVG_200D BREADTH    PX_LAST MOV_AVG_200D BREADTH
date                                                                       
1997-10-06       93.75      93.2863       1     332.55       339.45       0
1997-10-07       93.78      93.2881       1     331.45       339.27       0
1997-10-08       93.65      93.2892       1     333.25       339.09       0
1997-10-09       93.64      93.2904       1     327.75       338.90       0
1997-10-10       93.59      93.2913       1     329.65       338.74       0

如果您只有这 4 列,您可以像下面这样插入 2 BREADTH 列:

df.insert(2,('ed12 comdty','BREADTH'),(df.iloc[:,0] > df.iloc[:,1]).astype(int))

df.insert(len(df.columns),('xau curncy','BREADTH'),(df.iloc[:,-2] > df.iloc[:,-1]).astype(int))

df
Out[1495]: 
           ed12 comdty                      xau curncy                     
               PX_LAST MOV_AVG_200D BREADTH    PX_LAST MOV_AVG_200D BREADTH
Date                                                                       
1997-10-06       93.75      93.2863       1     332.55       339.45       0
1997-10-07       93.78      93.2881       1     331.45       339.27       0
1997-10-08       93.65      93.2892       1     333.25       339.09       0
1997-10-09       93.64      93.2904       1     327.75       338.90       0
1997-10-10       93.59      93.2913       1     329.65       338.74       0