Установить столбец DataFrame с несколькими индексами по сериям с индексом - PullRequest
2 голосов
/ 16 мая 2019

Я борюсь с фреймом данных MultiIndex (a), который требует, чтобы столбец x был установлен на b, который не является MultiIndex и имеет только 1 уровень индекса (первый уровень 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 ]

1 голос
/ 16 мая 2019

Я думаю, что вы хотите объединить a и B. вам следует рассмотреть возможность использования функций concat, merge или join.

0 голосов
/ 16 мая 2019

Я не могу придумать ни одной строки, так что вот многошаговый подход:

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
0 голосов
/ 16 мая 2019

Сначала я сбрасываю мультииндекс из 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 относится к индексу aи 0 относится к индексу 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 относится к индексу b)

a = a.reset_index()

print(a)
   a  b  x
0  1  b  4
1  2  b  5
2  3  b  6
a.loc[0, 'x'] = b.loc[1,'x']
a = a.set_index(['a','b'])

print(a)
     x
a b   
1 b  9
2 b  5
3 b  6
0 голосов
/ 16 мая 2019

Вы пытаетесь использовать 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...