有没有办法将新列添加到仅与一个级别对齐的 pandas 多索引?

Is there a way to add a new column to a pandas multiindex that only aligns with one level?

我正在寻找一种将列添加到多索引数据框的简洁方法,其中值仅在每个级别=0 重复一次。

例如,

我要为此添加一列:

Index level=0 Index level=1 Value (x)
A 1 300
2 850
3 2000
B 1 100
2 70
3 400

为了得到这个:

Index level=0 Index level=1 Value (x) Value (y)
A 1 300 Yellow
2 850
3 2000
B 1 100 Red
2 70
3 400

想要这个:

Index level=0 Index level=1 Value (x) Value (y)
A 1 300 Yellow
2 850 Yellow
3 2000 Yellow
B 1 100 Red
2 70 Red
3 400 Red

我不确定如何最好地在这里创建一个 table 来显示我所希望的,但对我来说重要的部分是 y 对应于索引级别 = 0 的所有行,但是对于索引级别=1 的每个增量不重复。我确定我可以在 y 列中添加空值的其他行,但我认为可能有更优雅的方法。

使用pd.IndexSlice:

idx = pd.IndexSlice
df.loc[idx[:, 1], 'Color'] = ['Yellow', 'Red']
print(df)

# Output
     Value   Color
A 1    300  Yellow
  2    850     NaN
  3   2000     NaN
B 1    100     Red
  2     70     NaN
  3    400     NaN

或仅使用 slice:

df.loc[(slice(None), 1), 'Color'] = ['Yellow', 'Red']
print(df)

# Output
     Value   Color
A 1    300  Yellow
  2    850     NaN
  3   2000     NaN
B 1    100     Red
  2     70     NaN
  3    400     NaN

你没有具体说明你的高/低是如何确定的,所以我在字典中硬编码它们:

# Create the data frame
index = pd.MultiIndex.from_product([['A', 'B'], [1,2,3]])
df = pd.DataFrame({
    'x': [300, 850, 2000, 100, 70, 400]
}, index=index)

# The transformation
def f(col):
    y_values = {
        'A': 'High',
        'B': 'Low'
    }
    level0 = col.index[0][0]
    return [y_values[level0]] + [''] * (len(col) - 1)

df['y'] = df.groupby(level=0).transform(f)

遍历 index0 并为 index0 中的每种新数据类型的新列赋值:

c=0
for i in df.index:
    if i[0] != c:
        #put your code here to add values to new column
        c = i[0]