2016-05-18 12 views
13

Что такое эффективный способ получить диагональ квадрата DataFrame. Я ожидаю, что результатом будет Series с MultiIndex с двумя уровнями, первый из которых является индексом DataFrame, вторым уровнем которого являются столбцы DataFrame.pandas Диаграмма данных DataFrame

Настройка

import pandas as pd 
import numpy as np 

np.random.seed([3, 1415]) 
df = pd.DataFrame(np.random.rand(3, 3) * 5, 
        columns = list('abc'), 
        index = list('ABC'), 
        dtype=np.int64 
       ) 

Я хочу увидеть это:

print df.stack().loc[[('A', 'a'), ('B', 'b'), ('C', 'c')]] 

A a 2 
B b 2 
C c 3 

ответ

14

Если вы не возражаете против использования NumPy вы можете использовать numpy.diag

pd.Series(np.diag(df), index=[df.index, df.columns]) 

A a 2 
B b 2 
C c 3 
dtype: int64 
6

Вы могли бы сделать что-то вроде этого:

In [16]: 
midx = pd.MultiIndex.from_tuples(list(zip(df.index,df.columns))) 
pd.DataFrame(data=np.diag(df), index=midx) 

Out[16]: 
    0 
A a 2 
B b 2 
C c 3 

np.diag даст вам диагональные значения как массив н.п. , вы можете затем построить мультииндекс, запустив индекс и столбцы и передав это как желаемый индекс в DataFrame ctor.

На самом деле комплекс мультииндекс поколение не должны быть настолько сложными:

In [18]: 
pd.DataFrame(np.diag(df), index=[df.index, df.columns]) 

Out[18]: 
    0 
A a 2 
B b 2 
C c 3 

Но johnchase's answer является аккуратным

+1

Вы избили меня до этого 'numpy.diag' - хорошее решение. Нужно ли передавать mutliindex? не будет ли это работать? 'pd.Series (np.diag (df), index = [df.index, df.columns])' – johnchase

+0

@johnchase на самом деле это лучшее решение, я просто решил буквально сделать то, что ОП запросил – EdChum

+0

@johnchase, пожалуйста, отправьте ответ с этим. просто запустил его и работал – piRSquared

3

Вы также можете использовать iat в понятии списка, чтобы получить диагональ.

>>> pd.Series([df.iat[n, n] for n in range(len(df))], index=[df.index, df.columns]) 
A a 2 
B b 2 
C c 3 
dtype: int64 
Смежные вопросы