2015-11-25 4 views
0

Допустим, у меня есть данные:GroupBy с комбинациями категориальных переменных

pd.DataFrame({'index': ['a','b','c','a','b','c'], 'column': [1,2,3,4,1,2]}).set_index(['index']) 

, который дает:

 column 
index 
a   1 
b   2 
c   3 
a   4 
b   1 
c   2 

Тогда, чтобы получить среднее для каждой подгруппы можно было бы:

df.groupby(df.index).mean() 

     column 
index 
a   2.5 
b   1.5 
c   2.5 

Тем не менее, что я пытался достичь без постоянного циклирования и резки данных, как получить среднее значение для пар subgr невный?

Например, среднее значение & b составляет 2? Как будто их ценности были объединены.

выход будет что-то похожее на:

 column 
index 
a & a  2.5 
a & b  2.0 
a & c  2.5 
b & b  1.5 
b & c  2.0 
c & c  2.5 

Предпочтительно это предполагает манипулирование параметров в «GroupBy», но, как это, мне приходится прибегать к перекручиванию и нарезки. С возможностью построения всех комбинаций подгрупп в какой-то момент.

ответ

0

Моя текущая реализация:

import pandas as pd 
import itertools 
import numpy as np 

    # get all pair of categories here 
def all_pairs(df, ix): 
    hash = { 
     ix: [], 
     'p': [] 
    } 
    for subset in itertools.combinations(np.unique(np.array(df.index)), 2): 
     hash[ix].append(subset) 
     hash['p'].append(df.loc[pd.IndexSlice[subset], :]).mean) 

    return pd.DataFrame(hash).set_index(ix) 

который получает комбинацию, а затем добавляет их в том, что имеет затем строит обратно в кадр данных. Это Hacky хотя :(

+0

Я оставлю это здесь, если он не получит достаточного ответа – Rambatino

0

Вот реализация, которая использует мультииндексный и внешнее соединение, чтобы обрабатывать перекрестное соединение.

import pandas as pd 
from pandas import DataFrame, Series 
import numpy as np 

df = pd.DataFrame({'index': ['a','b','c','a','b','c'], 'column': [1,2,3,4,1,2]}).set_index(['index']) 

groupedDF = df.groupby(df.index).mean() 
# Create new MultiIndex using from_product which gives a paring of the elements in each iterable 
p = pd.MultiIndex.from_product([groupedDF.index, groupedDF.index]) 
# Add column for cross join 
groupedDF[0] = 0 
# Outer Join 
groupedDF = pd.merge(groupedDF, groupedDF, how='outer', on=0).set_index(p) 
# get mean for every row (which is the average for each pair) 
# unstack to get matrix for deduplication 
crossJoinMeans = groupedDF[['column_x', 'column_y']].mean(axis=1).unstack() 
# Create Identity matrix because each pair of itself will be needed 
b = np.identity(3, dtype='bool') 
# set the first column to True because it contains the rest of the unique means (the identity portion covers the first part) 
b[:,0] = True 
# invert for proper use of DataFrame Mask 
b = np.invert(b) 
finalDF = crossJoinMeans.mask(b).stack() 

Я предположил бы, что это может быть очищен и более кратким.

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