2016-03-28 13 views
1

Ich habe folgende Daten-Set:Python: wie man den Durchschnitt zwischen verschiedenen Pandas Datenrahmenspalten macht?

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 

ich wan, wie oft zu ID collaborate zu überprüfen und die Gesamthäufigkeit und den gewichteten Durchschnitt zählen. Die gewichtete ist die sum der Kollaboration über die sum der Weight. Die Ergebnisse sollten sein:

df1 

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

ich die Zusammenarbeit zwischen ID1 und ID2 auf diese Weise in falsche Weg verlasse mich

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

Antwort

0

Sie können zunächst Spalten sortieren ID1 und ID2 von numpy.ndarray.sort und dann groupby mit apply benutzerdefinierte Funktion 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

Sie

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

Dann sind nur die normalisierte Paare von Ihnen DataFrame (untere erste, höhere Sekunde). Jetzt können Sie nur diese GROUPBY und finden der gewichtete Durchschnitt:

>>> 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 

Um Ihre genaue zu erhalten erforderlich Datenrahmen wird etwas Hantieren mit den Spalten notwendig, aber es ist im Grunde der Code oben:

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 
Verwandte Themen