在组内排序而不更改组顺序?

2024-09-26 17:52:57 发布

您现在位置:Python中文网/ 问答频道 /正文

在网上找不到最新的答案。我的问题本质上与this question相同,也就是说,我想在group内按revenue排序,而不改变数据集中group的顺序

该线程的答案是错误的,它之所以有效,是因为示例中只有两个组恰好按反字母顺序排列

当我尝试df.groupby('group').sort_values('revenue')时,我得到错误'DataFrameGroupBy' object has no attribute 'sort_values'

我该怎么做

示例数据帧:

    name    group   revenue
0   Name1   GroupB  1
3   Name4   GroupA  4
4   Name5   GroupA  5
8   Name7   GroupC  9
1   Name2   GroupB  2
2   Name3   GroupB  3
5   Name6   GroupA  6
6   Name7   GroupC  7
7   Name7   GroupC  8

预期产出:

    name   group  revenue
2  Name3  GroupB        3
1  Name2  GroupB        2
0  Name1  GroupB        1
5  Name6  GroupA        6
4  Name5  GroupA        5
3  Name4  GroupA        4
8  Name7  GroupC        9
7  Name7  GroupC        8
6  Name7  GroupC        7

Tags: 数据答案name示例错误groupsortvalues
2条回答

为什么要使用groupby呢?您可以将多个sort_值调用链接在一起,以获得正确的排序顺序。e、 g.使用类似的数据链接问题,您希望按收入降序排序,但保持组升序,您可以这样做:

import pandas as pd

df = pd.DataFrame({'name': ['Name1','Name2','Name3','Name4','Name5','Name6', 'Name7', 'Name7', 'Name7'], 
    'group':['GroupB','GroupB','GroupB','GroupA','GroupA','GroupA','GroupC','GroupC','GroupC'],'revenue':[1,2,3,4,5,6,7,8,9]})

df.sort_values(by='revenue', ascending= False).sort_values(by='group')

这将返回:

name    group   revenue
5   Name6   GroupA  6
4   Name5   GroupA  5
3   Name4   GroupA  4
2   Name3   GroupB  3
1   Name2   GroupB  2
0   Name1   GroupB  1
8   Name7   GroupC  9
7   Name7   GroupC  8
6   Name7   GroupC  7

您可以创建一个新的临时列,将BAC转换为123,以便维护无序的顺序。然后,只需删除临时列。在回答#1中,这是更动态的,如果group列的值没有连续分组,那么这将起作用。对于答案2,它们必须是连续的(答案1和答案2的输入顺序不同)

更新的答案#1(每个注释-组在行中不是连续的,但我们仍然希望按照每个组中第一个值的出现顺序对它们进行正确排序。)代码[l for l in enumerate((df['group'].unique()))]将根据数据帧中group列的第一个值的顺序为每个组分配一个数字

In[1]:
    name    group   revenue
0   Name1   GroupB  1
3   Name4   GroupA  4
4   Name5   GroupA  5
8   Name7   GroupC  9
1   Name2   GroupB  2
2   Name3   GroupB  3
5   Name6   GroupA  6
6   Name7   GroupC  7
7   Name7   GroupC  8

dft = pd.DataFrame([l for l  in enumerate((df['group'].unique()))], columns=['group_number','group'])
df = pd.merge(df, dft, how='left', on='group').sort_values(['group_number', 'revenue'], ascending = [True, False])
df

Out[1]: 
    name   group  revenue  group_number
5  Name3  GroupB        3             0
4  Name2  GroupB        2             0
0  Name1  GroupB        1             0
6  Name6  GroupA        6             1
2  Name5  GroupA        5             1
1  Name4  GroupA        4             1
3  Name7  GroupC        9             2
8  Name7  GroupC        8             2
7  Name7  GroupC        7             2

我想在合并和排序之前突出显示enumerate行代码的dft输出

dft = pd.DataFrame([l for l  in enumerate((df['group'].unique()))], columns=['group_number','group'])
dft

Out[2]: 
   group_number   group
0             0  GroupB
1             1  GroupA
2             2  GroupC

答复#2

import pandas as pd
df = pd.DataFrame({'name': ['Name1','Name2','Name3','Name4','Name5','Name6', 'Name7', 'Name7', 'Name7'], 
    'group':['GroupB','GroupB','GroupB','GroupA','GroupA','GroupA','GroupC','GroupC','GroupC'],'revenue':[1,2,3,4,5,6,7,8,9]})
df['cs'] = (df['group'] != df['group'].shift(1)).cumsum()
df = df.sort_values(['cs', 'revenue'], ascending = [True, False])
df
Out[11]: 
    name   group  revenue  cs
2  Name3  GroupB        3   1
1  Name2  GroupB        2   1
0  Name1  GroupB        1   1
5  Name6  GroupA        6   2
4  Name5  GroupA        5   2
3  Name4  GroupA        4   2
8  Name7  GroupC        9   3
7  Name7  GroupC        8   3
6  Name7  GroupC        7   3

对于这两个答案,只需删除列:

df = df.drop('cs', axis=1)

Out[12]: 
    name   group  revenue
2  Name3  GroupB        3
1  Name2  GroupB        2
0  Name1  GroupB        1
5  Name6  GroupA        6
4  Name5  GroupA        5
3  Name4  GroupA        4
8  Name7  GroupC        9
7  Name7  GroupC        8
6  Name7  GroupC        7

相关问题 更多 >

    热门问题