2017-06-01 71 views
3

我已经做了一个例子,因为我的数据集的内容和细节可能是太多/不必要的解释,提供我的问题使用GROUPBY时,做一个加权和。虽然我的例子可能很愚蠢,但只要知道这个例子确实说明了我希望达到的目标(尽管规模要大得多),并且对于给定的问题非常重要。在这个例子中,假设我们有不同的用户(用字母表示)。每个用户共享多个帖子,并且不同的用户经常共享相同的帖子。然后我们得出一个重要性分数(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 

我很想示例代码,并建议如何解决这个问题!提前致谢。

+0

你可以做一个新的col “重要性”和“可靠性”之间乘积的乘积。然后你可以通过'user'来'groupby'。 – arnold

+0

你在说你想要的 - 对于用户共享的一些独特文本,对每个用户的重要性和可靠性评分的乘积求和。您的预期结果表似乎并未反映上述说法。相反,它会显示所有帖子的产品总和,而不是唯一的帖子。国际海事组织,应该在预期的结果表中再增加一列 - “共享”。 –

+0

非常感谢! –

回答

4

第一多个栏由mul然后groupby + sum

通过如Series柱的groupby优点是没有临时列是必要的。

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

非常感谢你! –

+0

很高兴能帮助,祝你好运! – jezrael

1

只要做到:

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

或者你可以预先创建的产品列,只是总结说:

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

(这些都假定一个用户不共享相同的文章超过一次)

2

这是刚从

PROJECT 
------- 
KILL 

项目矫枉过正...只是柜面你没有得到它。
请不要接受这个答案!这只是我玩得开心。是的,我相信这对其他许多人都有用。不,我不认为这是必要的。 @ 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 
+0

感谢分享! –

1

至于你的问题的措辞去,我想你想为每一个独特ImportanceReliability产品的总和,且每个独特用户

下面是类似的样本数据帧到your's-

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,从而获得所需result-

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

感谢您的帮助! –

+0

如果这解决了你的问题,那么你可以接受答案:-) –