基于pandas / python中多列的字符串对列中的值求和

时间:2018-05-04 08:46:46

标签: python pandas

我有一个包含4列的数据框。其中3列包含字符串值(人名),第4列包含int值(完成作业的工资)。

字符串值也不是唯一的,相同的字符串将在每列中显示多次,但每行不会超过一次。

data = {
    'worker1': ['Sam', 'Jack', 'Matt', 'Paul', 'Tim'],
    'worker2': ['Alex', 'Amy', 'Sam', 'Alice', 'Amanda'], 
    'worker3': ['Alice', 'Aaron', 'Tony', 'Jack', 'Sam'],
    'earnings': [4564552, 4573547, 3567567, 6357653, 7648576]}

df = pd.DataFrame(data, columns = ['worker1', 'worker2', 'worker3', 'earnings'])

print(df)

worker1    worker2    worker3    earnings
'Sam'      'Alex'     'Alice'    4564552
'Jack'     'Amy'      'Aaron'    4573547
'Matt'     'Sam'      'Tony'     3567567
'Paul'     'Alice'    'Jack'     6357653
'Tim'      'Amanda'   'Sam'      7648576

所以我需要的是总结与特定名称相关的所有收入,无论它是否显示在第1,2或3列。我不确定是否应该使用groupby函数,构建字典或去另一条路线。

这就是我想要完成的事情:

workers    total_earnings
Sam        16080695
Alex       4564552
Alice      10922205
Jack       10931200
Amy        4573547
Aaron      4573547
Matt       3567567
Tony       3567567
Paul       6357653
Tim        7648576
Amanda     7648576

我对熊猫很新,所以我在一个我不熟悉哪些功能可以用于此类的地方。我大多尝试使用groupby函数,但那是一场灾难。

任何帮助都将受到高度赞赏。

4 个答案:

答案 0 :(得分:1)

这里的困难来自数据框架的构建方式。所有工人姓名应该在一列中,并且他们各自的收入在第二列中。有一个术语“整洁的数据”值得了解https://en.wikipedia.org/wiki/Tidy_data

下面的解决方案重新排列数据框,一旦实现了这一点,就可以使用groupby轻松计算给定名称的总收入。

df_list = []
columns = df.columns.tolist()

for i in range(3):
    df_i = df.loc[:, [columns[i], 'earnings']]
    df_i.columns = ['worker', 'earnings']
    df_list.append(df_i)

df_1 = pd.concat(df_list)

earnings = df_1.groupby(['worker']).sum()

earnings
Out[50]: 
        earnings
worker          
Aaron    4573547
Alex     4564552
Alice   10922205
Amanda   7648576
Amy      4573547
Jack    10931200
Matt     3567567
Paul     6357653
Sam     15780695
Tim      7648576
Tony     3567567

答案 1 :(得分:1)

有点冗长,但你做了什么:

>>> df1 = pd.concat([df.groupby('worker1').sum(), df.groupby('worker2').sum(), df.groupby('worker3').sum()])
>>> df1.groupby(df1.index).sum()
        earnings
Aaron    4573547
Alex     4564552
Alice   10922205
Amanda   7648576
Amy      4573547
Jack    10931200
Matt     3567567
Paul     6357653
Sam     15780695
Tim      7648576
Tony     3567567

答案 2 :(得分:1)

我设法用以下代码做我想做的事。它确实有效,但我不知道这是正确的方法还是最有效的方法。对那些是否是解决这个问题的正确方法有更多经验的人进行一些验证将是有益的。感谢您提供的所有帮助!

df1 = df[['worker1', 'worker2', 'worker3', 'earnings']].copy()
df1.dropna(subset=['earnings'], inplace=True)
df1.reset_index(drop=True, inplace=True)

df1 = pd.melt(df1, id_vars = ['earnings'], value_name = 'workers', value_vars = ['worker1', 'worker2', 'worker3'])   

df1.drop('variable', axis=1, inplace=True)    
df1 = df1.groupby('workers')['earnings'].agg(np.sum)
df1 = pd.DataFrame({'workers':df1.index, 'Earnings':df1.values}) 

答案 3 :(得分:1)

我非常喜欢你的方法。至少对于上述问题中定义的数据框,您可以执行一些行。有意思的是,如果你使用groupby在我的另一个答案中编码的方式你得到一个数据框而不是一个系列,然后你可以将reset_index方法链接到同一行。

df1 = pd.melt(df, id_vars = ['earnings'], value_name = 'workers', value_vars = ['worker1', 'worker2', 'worker3'])   
df1 = df1.drop('variable', axis=1).groupby('workers').sum().reset_index()