从字典更新列中组的值

时间:2019-10-13 18:43:51

标签: python pandas dataframe dictionary pandas-groupby

我知道如何使用字典中的相关键和值更新数据框的列,但是更新列中几个组的 的最佳方法是什么>从字典里来?

因此,一种方法是执行groupby,然后从字典中的相应键读取组值。但是,对于我的数据集(拥有1400万行和125000个“ match_id”)来说,这花费了太长时间。


df = pd.DataFrame({'match_id': ['m1', 'm1', 'm1', 'm1', 'm1', 'm1', 'm2', 'm2', 'm2', 'm2', 'm2', 'm2', 'm3', 'm3', 'm3', 'm3'],
                   'name':['peter', 'mike', 'jeff', 'john', 'alex', 'joe', 'jeff', 'peter', 'alex', 'li', 'joe', 'tom', 'mike', 'john', 'tom', 'peter'],
                   'rank': [4, 3, 1, 2, 5, 6, 2, 4, 3, 1, 5, 6, 1, 3, 2, 4],
                   'rating': [1200, 1300, 1600, 1550, 1150, 1540, 1340, 1300, 1390, 1290, 1450, 1650, 1420, 1490, 1320, 1410]})

dict1 = {'m1': [5, 4, 1, 2, 6, 3], 'm2': [4, 5, 3, 6, 2, 1], 'm3': [2, 1, 4, 3]}

df_new = pd.DataFrame()
grouped = df.groupby('match_id', sort=False)
for id, dfg in grouped:
        dfm = dfg.copy()
        dfm['new_rank']= dict1[id]
        df_new = pd.concat([df_new, dfm], sort=True)

这将创建一个新列'new_rank',其中从dict1中为每个match_id提取值。

我还尝试了 map 函数,但是由于它不是针对组的,因此它只是将每根match_id的整个值列表粘贴到每一行上。

有什么有效的方法吗?

在旁注中,这是我想出的字典的方法,该字典根据“评分”列中的数字顺序来计算新排名(如果您还可以想到一种更好的方法来处理整件事,请让我知道):

dict1 = {}
grouped = df.groupby('match_id', sort=False)
for id, dfg in grouped:
    dfm = dfg.copy()
    dict1[id] = [len(dfm['rating'])-(sorted(dfm['rating'], reverse = False).index(x)) for x in dfm['rating']]

1 个答案:

答案 0 :(得分:2)

我之所以要求字典的逻辑,是因为我们可以在那里解决问题。您只想要Groupby.rank

df['new_rank'] = df.groupby('match_id')['rating'].rank(ascending=False).astype(int)

输出

   match_id   name  rank  rating  new_rank
0        m1  peter     4    1200         5
1        m1   mike     3    1300         4
2        m1   jeff     1    1600         1
3        m1   john     2    1550         2
4        m1   alex     5    1150         6
5        m1    joe     6    1540         3
6        m2   jeff     2    1340         4
7        m2  peter     4    1300         5
8        m2   alex     3    1390         3
9        m2     li     1    1290         6
10       m2    joe     5    1450         2
11       m2    tom     6    1650         1
12       m3   mike     1    1420         2
13       m3   john     3    1490         1
14       m3    tom     2    1320         4
15       m3  peter     4    1410         3