2016-06-21 3 views
2

У меня квадратная матрица в виде кадра данных в пандах. Он должен быть симметричным и почти равен, за исключением нескольких отсутствующих значений, которые я заполнил с 0. Я хочу использовать тот факт, что он должен быть симметричным, чтобы заполнить недостающие значения, взяв максимум абсолютного значения над df.ix [x, y] и df.ix [y, x]. То есть:Pandas applymap on multilevel dataframe

df = pd.DataFrame({'b': {'b': 1, 'a': 0,'c':-1}, 'a': {'b': 1, 'a': 1,'c':0},'c':{'c':1,'a':0,'b':0}}) 

>>> df 
    a b c 
a 1 0 1 
b 1 1 0 
c 1 -1 1 

должны стать:

>>> df 
    a b c 
a 1 1 1 
b 1 1 -1 
c 1 -1 1 

Сначала я думал использовать простой applymap с функцией что-то вроде:

def maxSymmetric(element): 
    if abs(element) > df.T.ix[element.column,element.row]: 
      return element 
    else return df.T.ix[element.column,element.row] 

Но не похоже, чтобы быть способ вызова индексов элемента внутри функции внутри applymap (см. related).

Итак, я попытался сделать многоуровневый dataframe исходной матрицы и ее транспонированной:

pd.concat([df,df.T],axis=0,keys=['o','t']) 
    a b c 
o a 1 0 1 
    b 1 1 0 
    c 1 -1 1 
t a 1 1 1 
    b 0 1 -1 
    c 1 0 1 

Теперь я хочу, чтобы извлечь правильный (отличен от нуля, если таковая имеется) элемент из любого «о» или «т» , для каждого элемента, используя аналогичную функцию, как указано выше. Но я не очень разбираюсь в multiindexing, и я не могу понять, как использовать applymap здесь, или если я должен использовать что-то еще.

Предложения?

ответ

2

Я думаю, вы можете сначала конвертировать df в numpy array, используйте numpy solution и последний создать DataFrame с constructor:

a = df.values 
print (pd.DataFrame(data=a + a.T - np.diag(a.diagonal()), 
        columns=df.columns, 
        index=df.index)) 

    a b c 
a 1 1 2 
b 1 1 -1 
c 2 -1 1 

Редактируйте комментарий:

print (df + df.T - df[df==df.T].fillna(0)) 
    a b c 
a 1.0 1.0 1.0 
b 1.0 1.0 -1.0 
c 1.0 -1.0 1.0 
+0

К сожалению, я должен был осветленной, что большинство значения уже симметричны (я отредактировал сообщение так, чтобы (a, c) охватывал этот случай). Но, исходя из вашего предложения, я думаю, что это сработает: df + df.T - df [df == df.T] .fillna (0) Если вы хотите отредактировать свой ответ, я соглашусь с ним :) – andbeonetraveler

+0

Я добавляю ваше предложение, но результат немного отличается. Это нормально? – jezrael

+0

Да, насколько я понимаю, что делает то, что я хочу - в основном такая же идея, просто не преобразовывая сначала в numpy. Всегда можно изменить типы данных вручную, если это проблема. Благодаря! Я отредактировал его, хотя, чтобы отразить изменения, внесенные мной в исходное сообщение. – andbeonetraveler

Смежные вопросы