在pandas

时间:2017-06-01 05:48:53

标签: python pandas sum grouping

我已经编写了一个示例,因为我的数据集的上下文和详细信息可能太多/没有必要解释来提出我的问题。虽然我的例子可能很愚蠢,但只要知道这个例子确实说明了我希望实现的目标(尽管规模要大得多),并且对于给定的问题非常重要。在这个例子中,假设我们有不同的用户(用字母表示)。每个用户共享多个帖子,不同的用户经常共享同一个帖子。然后我们得出一个重要性分数(0或1表示是否重要)和可靠性分数(从1-10开始)。尽管为了这个问题如何计算这些度量是完全无关紧要的,但想象重要性可能分析内容和上下文/当前事件,并且可靠性考虑了此源/用户的先前性能。目前尚不清楚重要性和可靠性之间是否存在关联

User       Share                      Importance            Reliability

 A         Carrots are                     0                     3
           good for eyesight

 B         Apple Cider Vinegar             1                     4
           is good for pain

 C         Garlic is good for breadth      0                     7

 A         Garlic is good for breadth      1                     6
 B         Carrots are good for eyesight   1                     9

这些数字可能没有意义 - 道歉无论如何,我想为每个考虑可靠性和重要性的文本做一些加权和。为此,我想找到每个唯一的文本(由共享列指示),并为共享该文本的所有用户的重要性和可靠性分数的乘积求和。因此,我得到类似的东西:

A   6
B   13
C   0

我想了解如何解决这个问题的示例代码和建议!提前谢谢。

4 个答案:

答案 0 :(得分:4)

mul之后的第一个多列,然后是groupby + sum

groupby按列Series的优点是不需要临时列。

df = pd.DataFrame({'User':['A','B','C','A','B'], 
                   'Importance':[0,1,0,1,1], 
                   'Reliability':[3,4,7,6,9]})
print (df)
   Importance  Reliability User
0           0            3    A
1           1            4    B
2           0            7    C
3           1            6    A
4           1            9    B

df1 = df.Importance.mul(df.Reliability).groupby(df['User']).sum().reset_index(name='col')
print (df1)
  User  col
0    A    6
1    B   13
2    C    0

答案 1 :(得分:2)

这只是来自

PROJECT
-------
 KILL

Project Overkill ...只是因为你没有得到它 请不要接受这个答案!这只是我玩得开心。是的,我相信这对许多其他人都有用。不,我不认为这是必要的。 @ jezrael的答案就是你想要的。

使用numba在一个非常简单的问题上干扰优化

from numba import njit
import pandas as pd
import numpy as np

u = df.User.values
i = df.Importance.values
r = df.Reliability.values
f, q = pd.factorize(u)

@njit
def wghtd_sum(i, r, f):
    o = np.zeros(f.max() + 1, dtype=np.int64)
    for j in range(r.size):
        o[f[j]] += r[j] * i[j]
    return o

pd.DataFrame(dict(User=q, col=wghtd_sum(i, r, f)))

<强>时序
微小数据

%%timeit
u = df.User.values
i = df.Importance.values
r = df.Reliability.values
f, q = pd.factorize(u)
pd.DataFrame(dict(User=q, col=wghtd_sum(i, r, f)))
1000 loops, best of 3: 446 µs per loop

%timeit df.groupby('User').apply(lambda g: (g.Importance*g.Reliability).sum()).reset_index(name='col')
100 loops, best of 3: 2.51 ms per loop

%timeit df.Importance.mul(df.Reliability).groupby(df['User']).sum().reset_index(name='col')
1000 loops, best of 3: 1.19 ms per loop

大数据

from string import ascii_uppercase

np.random.seed([3,1415])
df = pd.DataFrame(dict(
        User=np.random.choice(list(ascii_uppercase), 100000),
        Importance=np.random.randint(2, size=100000),
        Reliability=np.random.randint(10, size=100000)
    ))

%%timeit
u = df.User.values
i = df.Importance.values
r = df.Reliability.values
f, q = pd.factorize(u)
pd.DataFrame(dict(User=q, col=wghtd_sum(i, r, f)))
100 loops, best of 3: 2.45 ms per loop

%timeit df.groupby('User').apply(lambda g: (g.Importance*g.Reliability).sum()).reset_index(name='col')
100 loops, best of 3: 14.1 ms per loop

%timeit df.Importance.mul(df.Reliability).groupby(df['User']).sum().reset_index(name='col')
100 loops, best of 3: 4.45 ms per loop

答案 2 :(得分:1)

只是做:

df.groupby('User').apply(lambda g: (g.Importance*g.Reliability).sum())

或者您可以预先创建产品列,并将其总结:

df['Score'] = df.Importance * df.Reliability
df.groupby('User').Score.sum()

(这些都假设单个用户不会多次共享同一篇文章。)

答案 3 :(得分:1)

就问题的措辞而言,我认为您希望对每个唯一帖子和每个唯一用户ImportanceReliability的产品求和

此处的示例数据框类似于您的< - p>

df = pd.DataFrame({'User':['A','B','C','A','B'],'Share':['Random Post 1','Random post 2','Random Post 3','Random Post 3','Random Post 1'], 'Importance':[0,1,0,1,1],'Reliability':[3,4,7,6,9]})
=>
       Importance  Reliability      Share       User
0           0            3      Random Post 1    A
1           1            4      Random post 2    B
2           0            7      Random Post 3    C
3           1            6      Random Post 3    A
4           1            9      Random post 1    B

首先获得一个新列Product -

df['Product'] = df.Importance.mul(df.Reliability)
=>
       Importance  Reliability      Share       User  Product
0           0            3      Random Post 1    A       0
1           1            4      Random post 2    B       4
2           0            7      Random Post 3    C       0
3           1            6      Random Post 3    A       6
4           1            9      Random post 1    B       9

现在,只需按ShareUser进行分组,然后将Product加总即可获得所需的结果 -

df.groupby(['Share','User'])['Product'].sum().reset_index(name='Score')
=>
    Share      User
Random Post 1   A       0
                B       9
Random Post 3   A       6
                C       0
Random post 2   B       4