Pandas 使用多索引为部分列设置值

Pandas set values for part of column with multiindex

我确定有一个简单的方法可以做到这一点,但我似乎找不到它。 本质上,我有一个 DataFrameMultiIndex,我想用 Series 设置列的一部分(对应于第一个索引级别中的值)。但是,无论我尝试什么,值都被设置为 NaN,即使索引名称对齐。

我尝试过的例子:

import pandas as pd
import numpy as np

df = pd.DataFrame(np.arange(12).reshape(4, 3),
                  columns=['col1', 'col2', 'col3'],
                  index=pd.MultiIndex.from_product((('a1', 'a2'), ('b1', 'b2')),
                                                   names=['idx1', 'idx2']))
s = pd.Series([100, 101], index=['b1', 'b2'], name='col3')
df.loc['a1', 'col3'] = s

在此之后,我希望 df 成为

           col1  col2  col3
idx1 idx2                  
a1   b1       0     1   100
     b2       3     4   101
a2   b1       6     7     8
     b2       9    10    11

但它是

           col1  col2  col3
idx1 idx2                  
a1   b1       0     1   NaN
     b2       3     4   NaN
a2   b1       6     7   8.0
     b2       9    10  11.0

关于如何在没有 .to_numpy().to_list() 的情况下实现此目标的任何想法(从那时起我需要手动检查项目的顺序)一个班轮没有做像

这样荒谬的事情
df.loc['a1', 'col3'] = s.to_frame().eval('idx1 = "a1"').reset_index().set_index(['idx1', 'idx2'])

可以使用s.to_numpy()s.tolist():

>>> df.loc['a1', 'col3'] = s.to_numpy()
           col1  col2   col3
idx1 idx1                   
a1   b1       0     1  100.0
     b2       3     4  101.0
a2   b1       6     7    8.0
     b2       9    10   11.0

使用:

df.loc['a1', 'col3'] = [100, 101]

输出:

根据您的评论:

s = pd.Series([100, 101], index=['b1', 'b2'], name='col3')
s = s.to_list()
df.loc['a1', 'col3'] = s

具有相同的输出。

基于其他评论!:

s = pd.Series([100, 101], index=(('a1', 'b1'), ('a1', 'b2')), name='col3')
df.loc['a1', 'col3'] = s

输出:

假设您没有在 df 索引中不存在的 in s 值,您可以这样做:

df.loc[('a1', s.index), 'col3'] = s.values

这将独立于 s 的顺序工作

输出:

           col1  col2  col3
idx1 idx2                  
a1   b1       0     1   100
     b2       3     4   101
a2   b1       6     7     8
     b2       9    10    11