【问题标题】:pandas: changing values according to conditions within grouppandas:根据组内条件更改值
【发布时间】:2021-08-18 06:44:29
【问题描述】:

我试图弄清楚如何使用 pandas 调整同一组内的一些值。

在下面的df中,我有两组(111、222);在组内,对“频率”进行排名。但是,我想将组内具有相同“频率”的“排名”调整为具有相同的“排名”(升序)。

示例:group:111,freq 1 相同,分别排在第 5 和第 6 位;但是,我想将它们调整为相同的排名(显示在 adj_rank 列中)

+-----+------+------+----------+ |编号 |频率 |排名 | adj_rank | +-----+------+------+----------+ | 111 | 1 | 5 | 5 | | 111 | 1 | 6 | 5 | | 111 | 2 | 1 | 1 | | 111 | 3 | 2 | 2 | | 111 | 4 | 3 | 3 | | 111 | 5 | 4 | 4 | | 222 | 1 | 2 | 2 | | 222 | 2 | 1 | 1 | | 222 | 3 | 4 | 4 | | 222 | 3 | 5 | 4 | | 222 | 4 | 3 | 3 | | 222 | 5 | 6 | 6 | +-----+------+------+----------+

df 的代码

import pandas as pd
import numpy as np
data = {'id':[111,111,111,111,111,111,
             222,222,222,222,222,222],
'freq':[1,1,2,3,4,5,
        1,2,3,3,4,5],
'rank':[5,6,1,2,3,4,
        2,1,4,5,3,6],
'adj_rank':[5,5,1,2,3,4,
        2,1,4,4,3,6]}
df = pd.DataFrame(data)

感谢@Anurag Dabas 的建议,但是,当我扩展 df 时,使用您提供的解决方案时结果将关闭。如果你看下面的df,使用你提供的代码时,adj_rank(第一行)显示11,但是正确的值应该是4。请指教,谢谢。 扩展df:

╔═════╦══════╦══════╦══════════╗ ║ id ║ freq ║ rank ║ adj_rank ║ ╠═════╬══════╬══════╬══════════╣ ║ 333 ║ 1 ║ 11 ║ 11 ║ ║ 333 ║ 2 ║ 1 ║ 1 ║ ║ 333 ║ 2 ║ 2 ║ 1 ║ ║ 333 ║ 1 ║ 5 ║ 4 ║ ║ 333 ║ 1 ║ 6 ║ 4 ║ ║ 333 ║ 1 ║ 7 ║ 4 ║ ║ 333 ║ 1 ║ 8 ║ 4 ║ ║ 333 ║ 1 ║ 9 ║ 4 ║ ║ 333 ║ 3 ║ 3 ║ 3 ║ ║ 333 ║ 3 ║ 4 ║ 3 ║ ║ 333 ║ 1 ║ 10 ║ 4 ║ ╚═════╩══════╩══════╩══════════╝

扩展的df代码:

data = {'id':[333,333,333,333,333,333,
             333,333,333,333,333],
'freq':[1,2,2,1,1,1,        
        1,1,3,3,1],        
'rank':[11,1,2,5,6,7,8,        
        9,3,4,10,]}
df = pd.DataFrame(data)

非常感谢问候

【问题讨论】:

    标签: python pandas dataframe pandas-groupby


    【解决方案1】:

    尝试将['id','freq'] 的累积计数减去原始排名:

    df['adj_rank']=df['rank']-df.groupby(['id','freq']).cumcount()
    #df['adj_rank']=df['rank'].sub(df.groupby(['id','freq']).cumcount())
    

    df的输出:

        id  freq    rank    adj_rank
    0   111     1   5       5
    1   111     1   6       5
    2   111     2   1       1
    3   111     3   2       2
    4   111     4   3       3
    5   111     5   4       4
    6   222     1   2       2
    7   222     2   1       1
    8   222     3   4       4
    9   222     3   5       4
    10  222     4   3       3
    11  222     5   6       6
    

    更新:

    在减去 cumcount() 后,使用 sort_values() 然后 groupby ['id','freq'] 对数据帧的值进行排序,然后转换 rank 的第一个值,最后对 df 的 index 进行排序,使其位于初始位置:

    df['rank']=df['rank']-df.groupby(['id','freq']).cumcount()
    df=df.sort_values(['id','freq','rank'])
    df['rank']=df.groupby(['id','freq'],sort=False)['rank'].transform('first')
    df=df.sort_index()
    

    【讨论】:

    • 感谢您的输入,但是,当我展开 df 时,似乎有些不对劲。我已经更新了这个问题。好心提醒。谢谢
    • @ManOnTheMoon 这取决于您最初计算排名的方式
    • @Anurag Dabas 排名是使用频率出现的概率得出的。概率是按顺序计算的。例如,频率 1 的出现概率在 id 333 内为 0.1、0.11、0.12、0.13、0.14、0.15、0.16,因此,当使用“密集”进行排名时,频率 1 提供顺序排名(5 到 11)。但是,如前所述,我需要将组内相同的频率调整为相同的等级。
    • ps,更改为全局平均值进行概率计算不适用,因为我需要顺序计算的平均值。
    • 谢谢。它解决了这个问题。但是,jupyter 中似乎存在某种扭结。当我用完整的数据集尝试它时,有些值是关闭的。将尝试找到解决方案。再次感谢
    猜你喜欢
    • 2014-10-09
    • 2022-01-25
    • 2020-12-01
    • 2021-09-05
    • 1970-01-01
    • 1970-01-01
    • 2022-01-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多