2016-03-28 5 views
1

У меня есть следующий набор данных:Python: как сделать средний среди разных столбцов кадра данных pandas?

import pandas as pd 
df = pd.DataFrame({'ID1': [0, 1, 0, 2, 2, 4], 
'ID2': [1, 0, 3, 4, 4, 2], 
'Title': ['a', 'b', 'c', 'd', 'e', 'f'], 
'Weight': [3, 5, 1, 1, 5, 1]}) 

df 

ID1 ID2 Title Weight 
0  1  a  3 
1  0  b  5 
0  3  c  1 
2  4  d  1 
2  4  e  5 
4  2  f  1 

Я Вань, чтобы проверить, сколько раз ID сотрудничать и подсчитать общую частоту и взвешенное среднее. Утяжеленный является sum сотрудничества по sum из Weight. Результаты должны быть:

df1 

ID1 ID2 Total Weighted Av. 
1  0  2  0.25 
0  3  1   1 
2  4  3   0.5 

Я рассчитываю на неверном пути сотрудничество между ID1 и ID2 таким образом

df.groupby(['ID1','ID2']).size().reset_index() 

ответ

0

Вы можете сортировать столбцы ID1 и ID2 по numpy.ndarray.sort, а затем groupby с apply пользовательские функции f:

print df 
    ID1 ID2 Title Weight 
0 0 1  a  3 
1 1 0  b  5 
2 0 3  c  1 
3 2 4  d  1 
4 2 4  e  5 
5 4 2  f  1 

id1id2 = df[['ID1','ID2']].values 
id1id2.sort(axis=1) 
print id1id2 
[[0 1] 
[0 1] 
[0 3] 
[2 4] 
[2 4] 
[2 4]] 

df[['ID1','ID2']] = id1id2 
print df 
    ID1 ID2 Title Weight 
0 0 1  a  3 
1 0 1  b  5 
2 0 3  c  1 
3 2 4  d  1 
4 2 4  e  5 
5 2 4  f  1 
def f(x): 
    #print len(x) 
    #print x['Weight'].sum() 
    return pd.Series({'Total':len(x), 'Weighted Av.': len(x)/float(x['Weight'].sum()) }) 

print df.groupby(['ID1','ID2']).apply(f).reset_index() 
    ID1 ID2 Total Weighted Av. 
0 0 1 2.0  0.250000 
1 0 3 1.0  1.000000 
2 2 4 3.0  0.428571 
1

Предположим, вы определяете

pairs = df.apply(lambda r: (min(r.ID1, r.ID2), max(r.ID1, r.ID2)), axis=1) 

Тогда это только нормированный пары из вас DataFrame (ниже сначала, более высокая секунда). Теперь вы можете просто GroupBy их, и найти средневзвешенную:

>>> df.groupby(pairs).apply(lambda g: len(g)/float(g.Weight.sum())) 
(0, 1) 0.250000 
(0, 3) 1.000000 
(2, 4) 0.428571 
dtype: float64 

Чтобы получить ваш точный требуется DataFrame, некоторые возился с колонками необходимо, но это в основном выше код:

pairs = df.apply(lambda r: (min(r.ID1, r.ID2), max(r.ID1, r.ID2)), axis=1) 
weighted = pd.merge(
    df.groupby(pairs).apply(lambda g: len(g)/float(g.Weight.sum())).reset_index(), 
    df.groupby(pairs).size().reset_index(), 
    left_index=True, 
    right_index=True) 
weighted['ID1'] = weighted['index_x'].apply(lambda p: p[0]) 
weighted['ID2'] = weighted['index_x'].apply(lambda p: p[1]) 
weighted['Total'] = weighted['0_x'] 
weighted['Weighted Ave'] = weighted['0_y'] 
weighted = weighted[['ID1', 'ID2', 'Total', 'Weighted Ave']] 
>>> weighted 
    ID1  ID2  Total Weighted Ave 
0 0 1 0.250000 2 
1 0 3 1.000000 1 
2 2 4 0.428571 3 
Смежные вопросы