2016-05-31 4 views
2

하나의 레코드가 하나 이상의 그룹에 속할 수있는 퍼지 groupby을 수행해야합니다. groupby 다중 값 열

나는 이런 DataFrame 있습니다

test = pd.DataFrame({'score1' : pandas.Series(['a', 'b', 'c', 'd', 'e']), 'score2' : pd.Series(['b', 'a', 'k', 'n', 'c'])}) 

출력 : enter image description here

그룹 키의 조합이어야한다 :

score1 score2 
0 a  b 
1 b  a 
2 c  k 
3 d  n 
4 e  c 

는이 같은 그룹이하고자하는 score1score2 사이의 고유 한 값 0 레코드는 점수 값이 모두 포함되어 있으므로 그룹 ab이어야합니다. 비슷한 기록 1은 그룹 ba이어야합니다. 레코드 2은 그룹 ck 등이어야합니다.

은이 같은 두 개의 열에서 GROUPBY 일을 시도했다 :

내가 튜플로 그룹 키를 얻을 그러나
In [192]: score_groups = pd.groupby(['score1', 'score2']) 

- (1, 2), (2, 1), (3, 8) , 등, 레코드가 여러 그룹에있을 수있는 고유 한 그룹 키 대신. 출력은 다음과 같습니다

In [192]: score_groups.groups 

Out[192]: {('a', 'b'): [0], 
      ('b', 'a'): [1], 
      ('c', 'k'): [2], 
      ('d', 'n'): [3], 
      ('e', 'c'): [4]} 
또한

, 내가 나중에 다른 동작을 사용하고 있기 때문에 인덱스가을 보존해야합니다. 도와주세요!

+0

아마도 데이터 프레임을 옮겨야 할 것 같습니다. 컬럼이 'index, score_name, score'인 경우 이것은 사소한 것입니다. pandas.melt를보고 데이터 프레임을 변환하십시오. – Alex

+0

그래서 .... 원래 색인을 인내해야합니다. – Alex

+0

예, GroupBy 객체의 실제 그룹에 액세스해야 그룹의 일부 작업을 수행 할 수 있습니다. 내 대답을 게시했습니다. – lostsoul29

답변

2

두 개의 columns을 하나의 column에 결합합니다. pd.concat() :

s = s.groupby('grp').apply(lambda x: x.val.tolist()) 

a [0, 1] 
b [1, 0] 
c [2, 4] 
d  [3] 
e  [4] 
k  [2] 
n  [3] 

또는, 당신이 선호하는 경우 dict :

s = pd.concat([test['score1'], test['score2'].rename(columns={'score2': 'score1'})]).reset_index() 
s.columns = ['val', 'grp'] 

    val grp 
0 0 a 
1 1 b 
2 2 c 
3 3 d 
4 4 e 
5 0 b 
6 1 a 
7 2 k 
8 3 n 
9 4 c 

그리고 'grp'에 다음 .groupby() 및 수집 'val'list A의

s.to_dict() 

{'e': [4], 'd': [3], 'n': [3], 'k': [2], 'a': [0, 1], 'c': [2, 4], 'b': [1, 0]} 

또는 같은 효과에의 단일 단계, 열 이름 변경 건너 뛰기 :

test.unstack().reset_index(-1).groupby(0).apply(lambda x: x.level_1.tolist()) 

a [0, 1] 
b [1, 0] 
c [2, 4] 
d  [3] 
e  [4] 
k  [2] 
n  [3] 
+0

연결 작업은 새 인덱스 값을 추가합니다. 나는 다른 것들을 사용하기 때문에 보존 된 인덱스가 필요합니다. 원본 인덱스를 복제하는 별도의 열을 실제로 만들었습니다. 실제 인덱스 대신이 컬럼의 값을 저장하는'groupby()'를 할 수 있습니까? – lostsoul29

+0

방금 ​​원본 데이터가 변경된 것처럼 내 대답을 업데이트했거나 이전에 잘못 복사 했습니까? 나는'index' 값이 적절히 포착 된 것으로 생각 하는가? – Stefan

+0

네 말이 맞아. 나는 나의 데이터를보다 자세하게 표현하기 위해 질문을 변경했다. 당신의 대답은 정확한 색인을 제공하지만,'apply()'함수 때문에 원래의'GroupBy' 객체와 그 내용에 대한 접근은 손실됩니다. 사전 값을 사용하여 원래의 dataFrame에서 행을 가져올 수 있지만'GroupBy' 객체 자체를 갖는 것이 좋습니다. – lostsoul29

0

조작하기 쉽도록 데이터를 재구성합니다 (동일한 데이터에 대해 여러 개의 값을 갖는 열은 항상 두통을 유발합니다).

import pandas as pd 

test = pd.DataFrame({'score1' : pd.Series([1, 2, 3, 4, 5], index=['a', 'b', 'c', 'd', 'e']), 'score2' : pd.Series([2, 1, 8, 9, 3], index=['a', 'b', 'c', 'd', 'e'])}) 

test['name'] = test.index 
result = pd.melt(test, id_vars=['name'], value_vars=['score1', 'score2']) 

    name variable value 
0 a score1  1 
1 b score1  2 
2 c score1  3 
3 d score1  4 
4 e score1  5 
5 a score2  2 
6 b score2  1 
7 c score2  8 
8 d score2  9 
9 e score2  3 

지금 당신은 당신의 가치에 대해 하나의 컬럼을 가지고 있고 그것은 당신의 이름 열을 기준으로 점수 또는 선택을 GROUPBY 쉽게 :

Stefan의 도움을 사용
hey = result.groupby('value') 
    hey.groups 
    #below are the indices that you care about 
    {1: [0, 6], 2: [1, 5], 3: [2, 9], 4: [3], 5: [4], 8: [7], 9: [8]} 
+0

이것은 잘 작동하지만 인덱스를 보존하지 않습니다. 'result'에서 groupby를 할 때, 그룹 내의 인덱스는 원래의 데이터 프레임이 아닌 결과가됩니다. 또한,'result.groupby ('value')'는 원래 데이터 세트의 행이 아닌'result' 행의 그룹을 포함합니다. 내 질문을 업데이트했습니다. – lostsoul29

+0

@ lostsoul29 - 예, 새로운 데이터 프레임에 대한 인덱스입니다. 그 결과에 색인을 붙이기 만하면 원하는 결과를 얻을 수 있습니다. 원래 색인을 보존해야하는 경우 색인이 아닌 컬럼으로 저장해야합니다. – Alex

1

, 나는 이런 식으로 해결.

In (283): frame1 = test[['score1']] 
      frame2 = test[['score2']] 
      frame2.rename(columns={'score2': 'score1'}, inplace=True) 

      test = pandas.concat([frame1, frame2]) 

      test 

Out[283]: 
    score1 
0 a 
1 b 
2 c 
3 d 
4 e 
0 b 
1 a 
2 k 
3 n 
4 c 

중복 색인에 유의하십시오. 색인은 보존되어 있으며, 이는 내가 원했던 것입니다.이제는 업무별로 그룹을 구성 할 수 있습니다.

In (283): groups = test.groupby('score1') 

      groups.get_group('a') # Get group with key a 

Out[283]: 
    score1 
0 a 
1 a 

In (283): groups.get_group('b') # Get group with key b 

Out[283]: 
    score1 
1 b 
0 b 

In (283): groups.get_group('c') # Get group with key c 

Out[283]: 
    score1 
2 c 
4 c 

In (283): groups.get_group('k') # Get group with key k 

Out[283]: 
    score1 
2 k 

팬더가 중복 된 경우에도 정확한 색인으로 행을 검색하는 방법에 당황 스럽습니다. 이해할 수 있듯이 그룹 별 작업은 역 색인 데이터 구조를 사용하여 행에 참조 (인덱스)를 저장합니다. 어떤 통찰력이라도 대단히 감사하겠습니다. 이 질문에 답한 사람은 누구나 답변을 수락 할 것입니다.