Добавление двух значений из двух столбцов и присвоение результата третьему столбцу в многоиндексном фрейме данных pandas

#python #python-3.x #pandas #multi-index

#python #python-3.x #pandas #многоиндексный

Вопрос:

У меня есть фрейм данных Pandas:

 a=[1,1,1,2,2,2,3,3,3]
dic={'A':a}

df=pd.DataFrame(dic)
  

Я применяю мультииндекс к этому df:

 index=[(1,'a'),(1,'b'),(1,'c'),(2,'a'),(2,'b'), (2, 'c'),(3,'a'),(3,'b'), (3,'c')]
df.index=pd.MultiIndex.from_tuples(index, names=['X','Y'])
  

Я добавляю новый столбец:

 df['B']='-'
  

Теперь у меня есть df:

        A   B 
X Y          
1 a    1   -
  b    1   -
  c    1   -
2 a    2   -
  b    2   -
  c    2   -
3 a    3   -
  b    3   -
  c    3   -
  

По сути, я хочу циклически проходить уровень = ‘X’ мультииндекса, добавляя один уровень к другому, а затем присваивая значения столбцу=’B’

Вот как я думал об этом:

 dex=[]
for idx, select_df in df.groupby(level=0):
    dex.append(idx)
#gives me a list of level='X' keys

dex_iter=iter(dex)
#creates an iterator from that list

last=next(dex_iter)
#gives me the first value of that list of keys, and moves the iterator to the next value

for i in dex_iter:
    
    df.loc[i,'B']=df.loc[i,'A'] df.loc[last,'A']
    last=i
  

Мой ОЖИДАЕМЫЙ результат:

       A   B
X Y        
1 a   1   -
  b   1   -
  c   1   -
2 a   2   3
  b   2   3
  c   2   3
3 a   3   5
  b   3   5
  c   3   5
  

Вместо этого я получаю:

       A    B
X Y        
1 a   1    -
  b   1    -
  c   1    -
2 a   2  NaN
  b   2  NaN
  c   2  NaN
3 a   3  NaN
  b   3  NaN
  c   3  NaN
  

Очевидно, это связано с некоторой особенностью присвоения значений мультииндексу. Но я не могу найти способ решить эту проблему.

Ответ №1:

Давайте попробуем groupby , first и shift :

 df.groupby(level=0)['A'].first().shift()

X
1    NaN
2    1.0
3    2.0
Name: A, dtype: float64

tmp = df.index.get_level_values(0).map(df.groupby(level=0)['A'].first().shift())
print (tmp)
# Float64Index([
#    nan, nan, nan, 1.0, 1.0, 1.0, 2.0, 2.0, 2.0], dtype='float64', name='X')
  

Это дает вам значения, которые вам нужно добавить к «A», чтобы получить «B»:

 df['B'] = df['A']   tmp
df

     A    B
X Y        
1 a  1  NaN
  b  1  NaN
  c  1  NaN
2 a  2  3.0
  b  2  3.0
  c  2  3.0
3 a  3  5.0
  b  3  5.0
  c  3  5.0