2017-01-18 5 views
2

Рассмотрим dataframe:панды агрегация - расчеты между столбцами

np.random.seed(0) 
df_agg = pd.DataFrame({'A' : ['foo', 'bar', 'foo', 'bar', 
           'foo', 'bar', 'foo', 'foo'], 
         'C' : np.random.choice(2, 8)}) 

я хотел бы, чтобы вычислить, сгруппированных по A следующие столбцы:

  • Количество элементов
  • Количество Правда в C
  • Процент True в C
  • Количество Ложные в C
  • Процент Ложные в C

Первые три элемента являются простыми с использованием агрегирования:

aggregations = { 
    'C': { 
     'Number of elements': 'count', 
     'Number of True':sum, 
     'Percentage of True': 'mean' 
    } 
} 
df_tab = df_agg.groupby('A').agg(aggregations) 
print df_tab 

И выход:

     C         
    Number of elements Number of True Percentage of True 
A              
bar     3    2   0.666667 
foo     5    4   0.800000 

Однако я не знаю, как, в той же совокупности, вычислять столбцы, которые являются комбинацией других столбцов - количество и процент Fals е.

В качестве обходного пути, я могу это сделать:

df_tab = df_tab['C'] #flatten 
df_tab['Number of False'] = df_tab['Number of elements'] - df_tab['Number of True'] 
df_tab['Percentage of False'] = 1 - df_tab['Percentage of True'] 

Какой будет уступать то, что я хочу, но я задаюсь вопросом, как сделать все это сразу.

 Number of elements Number of True Percentage of True Number of False Percentage of False 
A                         
bar     3    2   0.666667    1    0.333333 
foo     5    4   0.800000    1    0.200000 
+0

Я думаю, что ваш выбор: 1) определить вторичные столбцы, такие как «число ложных», и 2) создать вторичный фрейм данных и добавить его в 'df_tab'. – periphreal

ответ

1

Ответ на следующий quesiton из that comment:

Предполагая, что мне нужно более сложные вычисления и ссылки на другие столбцы. Есть ли способ, как обратиться к колонке, например, лямбда- функция

Предположим, что мы имеем иметь следующий DF:

In [62]: %paste 
df = pd.DataFrame(
{'A': {0: 'foo', 
    1: 'bar', 
    2: 'foo', 
    3: 'bar', 
    4: 'foo', 
    5: 'bar', 
    6: 'foo', 
    7: 'foo'}, 
'C': {0: 0, 1: 1, 2: 1, 3: 0, 4: 1, 5: 1, 6: 1, 7: 1}, 
'X': {0: 0.56804456109393231, 
    1: 0.92559663829266103, 
    2: 0.071036058197886942, 
    3: 0.087129299701540708, 
    4: 0.020218397440325719, 
    5: 0.832619845547938, 
    6: 0.77815675094985048, 
    7: 0.87001214824681916}}) 
## -- End pasted text -- 

In [63]: df 
Out[63]: 
    A C   X 
0 foo 0 0.568045 
1 bar 1 0.925597 
2 foo 1 0.071036 
3 bar 0 0.087129 
4 foo 1 0.020218 
5 bar 1 0.832620 
6 foo 1 0.778157 
7 foo 1 0.870012 

Решение:

groupby.GroupBy.apply() дает мы имеем доступ ко всем столбцам в сгруппированном блоке DF:

In [78]: %paste 
def f(grp): 
    return pd.DataFrame({ 
       'Number of elements':len(grp), 
       'Number of True': grp['C'].sum(), 
       'Percentage of True': grp['C'].mean(), 
       'XXX': grp['C'].mean()/grp['X'].sum()}, # <--- here we access different columns... 
       index=[grp.name]) 
## -- End pasted text -- 

In [79]: df.groupby('A', as_index=False).apply(f) 
Out[79]: 
     Number of True Number of elements Percentage of True  XXX 
0 bar    2     3   0.666667 0.361269 
1 foo    4     5   0.800000 0.346700 
3

вы можете использовать лямбда-функции:

In [43]: aggregations = { 
    ...:  'C': { 
    ...:   'Number of elements': 'count', 
    ...:   'Number of True':sum, 
    ...:   'Percentage of True': 'mean', 
    ...:   'Number of False': lambda x: len(x) - np.count_nonzero(x), 
    ...:   'Percentage of False': lambda x: 1 - x.mean() 
    ...:  } 
    ...: } 
    ...: 
    ...: df_agg.groupby('A').agg(aggregations) 
    ...: 
Out[43]: 
        C 
    Number of False Percentage of False Number of True Number of elements Percentage of True 
A 
bar    1   0.333333    2     3   0.666667 
foo    1   0.200000    4     5   0.800000 
+0

Мне это нравится, хорошая идея. В этом конкретном случае это сработает. Но при условии, что мне нужны более сложные вычисления и обратитесь к другим столбцам. Есть ли способ обращения к столбцу в, например, лямбда-функции? – HonzaB

+0

@HonzaB, это будет сложно, поскольку AFAIK '.agg()' будет применяться отдельно к отдельным столбцам – MaxU

+0

@HonzaB, можете ли вы привести пример, где вам нужно будет получить доступ к другим столбцам? – MaxU

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