2016-09-02 2 views
1

다음은 내가 쓴 글의 dr; 세부 사항은 다음과 같습니다. SQL 쿼리는 [person 1 id], [person 2 id] 및 [group에 함께 있었던 횟수] 필드가있는 테이블을 제공합니다. 저는 정사각형 인 판다 (pandas) 데이터 프레임으로 변환하고 싶습니다. 1 인당 1 열, 1 인당 1 열, 각 요소의 값은 그룹에 함께 있었던 횟수입니다. 내 결과의 행을 살펴본 후 한 번에 하나의 요소 만 채우는 것보다 더 우아한 방법을 찾고 있습니다.자체 조인에서 Square pandas 데이터 프레임으로 SQL 결과 변환


person_id에 대한 열과 assignment_id에 대한 열이있는 할당 테이블이있는 데이터베이스가 있습니다. 너무 다른 물건을 가지고 있지만, 여기에 우리의 목적을 위해,이 중요한 것입니다 :

SELECT person_id, assignment_id FROM assignments; 
 
person_id | assignment_id 
----------+-------------- 
     385 |   42 
     163 |   29 
     51 |   42 
     385 |   37 
     163 |   37 
     ... 

내가 두 사람이 같은 과제에왔다 얼마나 자주보고 싶어요. 그래서 내가 할 :

같은 출력을 제공
SELECT a1.person_id AS p1_id, a2.person_id AS p2_id, COUNT(*) 
FROM assignments AS a1 
INNER JOIN assignments AS a2 ON a1.assignment_id = a2.assignment_id AND a1.person_id < a2.person_id 
GROUP BY a1.person_id, a2.person_id 

:

 
p1_id | p2_id | count 
------+-------+------ 
    51 | 385 | 1 
    163 | 385 | 1 
     ... 

가 지금은 각 사람에 대한 행으로 dataframe에 데이터를 액세스하고 덤프하려는 파이썬 스크립트를 짓고 있어요, 각 사람에 대한 열 및 할당을 공유 한 횟수가있는 셀이 있습니다. 그래서 결과물은 다음과 같습니다. (셀에 무엇이 들어 있는지 신경 쓰지 않습니다. 0 또는 할당 된 숫자가 될 수 있습니다.) 첫 번째 행과 열의 위치가) 형식 :

 
p1_id | p_51 | p_163 | p_385 
-------+--------+--------+-------- 
    51 | * | 0 | 1 
    163 | 0 | * | 1 
    385 | 1 | 1 | * 

나는 약 20 명해야합니다, 그래서 그냥 하나 하나를 값을 설정하는 것이 잴 성능을 해치지 않을 것입니다,하지만 난 더 큰있을 때 좋은 연습을 배우려고 노력하고있어 데이터 세트. 이런 식으로 할 수있는 올바른 방법은 무엇입니까?

(즉, 그것을 처리하는 가장 좋은 방법이라면 내가 SQL 쿼리를 수정하는 개방적이야.)

답변

1

당신은 그들에 합류뿐만 아니라 복용하여 str 및 집계를 입력하는 데 필요한 열을 변환 한 후 groupby를 사용할 수 있습니다 그들의 카운트.

df[['person_id', 'assignment_id']] = df[['person_id', 'assignment_id']].astype(str) 

df = df.groupby(['assignment_id'], as_index=False, sort=False)['person_id'] \ 
     .agg({'col':','.join})['col']           \ 
     .str.split(',').apply(lambda x: sorted(x, reverse=True))    \ 
     .apply(pd.Series).add_prefix('p_id_')         \ 
     .set_index('p_id_0', drop=False) 

같이 인덱스, p_id_0 대한 표시기 변수를 구하는 get_dummies을 사용하여 더욱 간단하게 할 수 :

df1 = pd.get_dummies(df['p_id_1']).add_prefix('p_') 
print (df1) 

     p_163 p_385 
p_id_0    
51  0.0 1.0 
163  0.0 0.0 
385  1.0 0.0 

df2 = pd.get_dummies(df['p_id_0']).add_prefix('p_') 
print (df2) 

     p_163 p_385 p_51 
p_id_0      
51  0.0 0.0 1.0 
163  1.0 0.0 0.0 
385  0.0 1.0 0.0 

을이어서 0의 인덱싱 된 프레임의 모든 값을 매핑 한 후 이러한 개별 dataframes을 연결, 열 이름이 같은 동일한 열을 그룹화합니다.

df_final = pd.concat([df1, df2.applymap(lambda x: 0)], axis=1).add_prefix('p_') 
print (df_final.groupby(df.columns, axis=1).sum()) 

     p_163 p_385 p_51 
p_id_0      
51  0.0 1.0 0.0 
163  0.0 0.0 0.0 
385  1.0 0.0 0.0 
+1

우수. 감사! –

관련 문제