Python:如何在不同的pandas数据框列之间做平均值?

时间:2016-03-28 22:12:42

标签: python pandas group-by

我有以下数据集:

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

我以错误的方式指望ID1ID2之间的合作

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

2 个答案:

答案 0 :(得分:1)

假设您定义

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

然后这些只是你DataFrame的标准化对(较低的第一个,较高的第二个)。现在你可以将它们分组,找到加权平均值:

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

答案 1 :(得分:0)

您可以先按numpy.ndarray.sortID1ID2列进行排序,然后使用groupby自定义函数fapply进行排序:

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