通过带有索引的系列设置Multi-Index DataFrame列

时间:2019-05-16 04:59:36

标签: python pandas dataframe

我正在努力使用MultiIndex数据帧(a),该数据帧要求列xb设置,该列不是MultiIndex且只有一个索引级别(第一个a级别)。我有一个更改这些值的索引(ix),这就是为什么我使用.loc[]进行索引的原因。问题在于a中缺少索引级别的填充方式不是我所需要的(请参见示例)。

>>> a = pd.DataFrame({'a': [1, 2, 3], 'b': ['b', 'b', 'b'], 'x': [4, 5, 6]}).set_index(['a', 'b'])
>>> a
     x
a b   
1 b  4
2 b  5
3 b  6

>>> b = pd.DataFrame({'a': [1, 4], 'x': [9, 10]}).set_index('a')
>>> b
    x
a    
1   9
4  10

>>> ix = a.index[[0, 1]]
>>> ix
MultiIndex(levels=[[1, 2, 3], [u'b']],
           codes=[[0, 1], [0, 0]],
           names=[u'a', u'b'])

>>> a.loc[ix]
     x
a b   
1 b  4
2 b  5
>>> a.loc[ix, 'x'] = b['x']
>>> # wrong result (at least not what I want)
>>> a
       x
a b     
1 b  NaN
2 b  NaN
3 b  6.0

>>> # expected result
>>> a
     x
a b   
1 b  9  # index: a=1 is part of DataFrame b
2 b  5  # other indices don't exist in b and...
3 b  6  # ... x-values remain unchanged
        # if there were more [1, ...] indices...
        # ...x would also bet set to 9

4 个答案:

答案 0 :(得分:1)

我认为您想合并a和B。您应该考虑使用concat,merge或join funcs。

答案 1 :(得分:0)

您尝试将1-索引框与2-索引框一起使用,只需使用values

编辑:

import pandas as pd

a = pd.DataFrame({'a': [1, 2, 3], 'b': ['b', 'b', 'b'], 'x': [4, 5, 6]}).set_index(['a', 'b'])
b = pd.DataFrame({'a': [1, 4], 'x': [9, 10]}).set_index('a')

a_ix = a.index.get_level_values('a')[[0, 1]]
b_ix = b.index    
mask = (b_ix == a_ix)

a.loc[mask, 'x'] = b.loc[mask,'x'].values

a:

        x
a   b   
1   b   9
2   b   5
3   b   6

答案 2 :(得分:0)

我想不出任何一线,所以这是一个多步骤的方法:

tmp_df = a.loc[ix, ['x']].reset_index(level=1, drop=True)
tmp_df['x'] = b['x']
tmp_df.index = ix

a.loc[ix, 'x'] = tmp_df['x']

输出:

        x
a   b   
1   b   9.0
2   b   5.0
3   b   6.0

编辑:我假设索引中的b是符号性的。否则,代码将从a.loc[ix, 'x']开始失败:

a = pd.DataFrame({'a': [1, 1, 2, 3], 
                  'b': ['b', 'b', 'b', 'b'], 
                  'x': [4, 5, 3, 6]}).set_index(['a', 'b'])

a.loc[ix,'x']给出:

a  b
1  b    4
   b    5
   b    4
   b    5
Name: x, dtype: int64

答案 3 :(得分:0)

我首先重置a的多索引,然后将其设置为(单列)a

a = a.reset_index()
a = a.set_index('a')

print(a)
   b  x
a      
1  b  4
2  b  5
3  b  6
print(b)
    x
a    
1   9
4  10

然后,使用loc进行所需的分配,并重新设置多索引

  • 现在,由于我们正在使用loc,因此您的ix = a.index[[0, 1]]类似于[1,0]1指的是a0的索引指b的索引)
a.loc[1, 'x'] = b.iloc[0,0]
a.reset_index(inplace=True)
a = a.set_index(['a','b'])

print(a)
     x
a b   
1 b  9
2 b  5
3 b  6

编辑:

或者,重置a的多索引,不要将其设置为单列索引。然后可以使用您的[0,1](指的是带有loc的索引值,而不是位置iloc)(0指的是a和{{1}的索引}指的是1的索引

b
a = a.reset_index()

print(a)
   a  b  x
0  1  b  4
1  2  b  5
2  3  b  6