2015-07-28 2 views
0

У меня есть DataFrame со многими описательных колоннами и несколько столбцов значений, например, следующие, где val1 и val2 ценности, а все остальное описывает эти значения:Совокупные (сумма) DataFrame через одну колонку или уровень мультииндексных

In [58]: countries = ['X', 'Y', 'Z']; sectors = ['A', 'B', 'C'] 
In [59]: ch = np.random.choice 
In [61]: df = pd.DataFrame(dict(c=ch(countries, 100), s1=ch(sectors, 100), s2=ch(sectors, 100), is_good=ch([True, False], 100), val1=np.random.random(100), val2=np.random.random(100))) 
In [62]: df.head() 
Out[62]: 
    c is_good s1 s2  val1  val2 
0 Z True B B 0.694949 0.145197 
1 X True A A 0.319551 0.548003 
2 X False A C 0.946967 0.220035 
3 X False B A 0.998087 0.902530 
4 Y False B C 0.303517 0.660556 

Скажите, что меня не интересует, является ли значение «хорошим» или нет, поэтому я хочу суммировать столбцы значений над is_good.

Обычно я хотел бы сделать:

In [63]: df.set_index(['c', 's1', 's2', 'is_good']).sum(level=['c', 's1', 's2']) 
Out[63]: 
      val1  val2 
c s1 s2      
X A A 2.170132 1.999072 
    B 2.038995 3.528096 
    C 4.041300 3.150400 
    B A 2.418448 2.011886 
    B 1.212810 1.489008 
    C 0.284823 0.961956 

, но это становится немного неуклюжим и подвержен ошибкам, когда есть много описательных колонн. (Это хорошо, но если бы было еще несколько, это было бы уже тяжело.)

Я действительно ищу операцию, которая указывает столбец is_good, а не specifying everything but that column.

ответ

1

Вы можете настроить его так:

val_cols = ['val1', 'val2'] 
descriptive_cols = df.columns.difference(val_cols) 
group_cols = descriptive_cols.difference(['is_good']) 
df.groupby(group_cols)[val_cols].sum() 

После того, как вы сделаете первоначальные определения, то вы можете заменить 'is_good' с любым другим столбцом или подмножеством столбцов, которые не заинтересованы в так что вы бы только сделать это один раз.

+0

+1 для использования 'df.columns.difference'. Никогда не видел этого раньше! Я всегда делаю '[c для c в df.columns, если c не в (some_list)]', но это slicker! Вам даже не нужны бит 'set()'. – LondonRob

+0

Да, вы также можете использовать операции набора по индексам типа '&, -, |, ^', но есть предупреждения об устаревании. Вместо этого рекомендуется использовать именованные методы, такие как '.intersection, .diff, .union, .sym_diff' и т. Д. Я отредактировал ответ, чтобы удалить ненужные вызовы' set' – JoeCondron

+0

Чтобы уточнить, все эти операции могут быть выполняется как по индексам строк, так и по столбцам – JoeCondron

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