그룹 순서를 변경하지 않고 그룹 내에서 정렬 하시겠습니까?

Aug 21 2020

이 온라인에서 최신 답변을 찾을 수없는 것 같습니다. 내가 가진 문제는 본질적 으로이 질문 과 동일합니다 . 즉, 내 데이터 세트 의 순서를 변경하지 않고 say revenue내 에서 정렬하고 싶습니다 .groupgroup

해당 스레드에 대한 대답은 잘못되었습니다. 예에서 반 알파벳 순서로 된 그룹이 두 개뿐이기 때문에 작동합니다.

시도 할 때 df.groupby('group').sort_values('revenue')오류가 발생 'DataFrameGroupBy' object has no attribute 'sort_values'합니다.

어떻게 할 수 있습니까?

샘플 DataFrame :

    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

답변

2 DavidErickson Aug 22 2020 at 00:50

당신은 그 변환 새 임시 열을 만들 수 B, AC에를 1, 2그리고 3당신이 정렬되지 않은 순서를 유지 그래서. 그런 다음 임시 열을 삭제하십시오. 답변 # 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

나는의 출력 강조하고 싶었 dftenumerate병합 및 정렬하기 전에 코드의 라인을.

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
quizzical_panini Aug 21 2020 at 23:58

왜 groupby를 사용합니까? 올바른 정렬 순서를 얻기 위해 여러 sort_values ​​호출을 함께 연결할 수 있습니다. 예를 들어 연결된 질문에 유사한 데이터를 사용하고 수익을 내림차순으로 정렬하고 오름차순으로 그룹을 유지하려면 다음을 수행 할 수 있습니다.

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