2016-08-29 3 views
2

Stack Overflow에 대한 첫 번째 질문에 대한 고유하고 흥미로운 문제가 있기를 바랍니다.수백 개의 열과 열 인덱스에 문자열로 결합하기

저는 현재 매우 큰 팬더 데이터 프레임에있는 기술 평가에 대한 데이터를 가지고 있습니다. 각 행은 학생을 나타내며 각 열은 특정 기술 평가에 대한 점수를 포함합니다. 전체적으로 약 200 개의 기술 평가가 있으며 각 학생은이 평가의 작은 하위 집합에서 점수를 얻습니다 (1 - 20 점수가 전형적이지만 일부 학생은 더 많은 점수를 가짐).

예 dataframe 구조 : 나는 우리가 다른 데이터 저장소로 가져올 수 있도록 다음과 같은 형식으로 각 학생에 대한 공백으로 구분 된 문자열로 변환이 데이터를 얻기 위해 시도하고

id skill1 skill2 skill3 skill4 skill5 .... 
1  10  50  NaN  3  NaN 
2  Nan  10  2  70  NaN 
3  23  NaN  45  NaN  5 

:

skill1:10 skill2:50 skill4:3 
skill2:10 skill3:2 skill4:70 

(평가 점수가없는 기술 목록에 추가되지 어떻게 알) 나는 모두를 결합하는 람다 함수를 만들었습니다 자신의 열 레이블 자체 기술 값 : I가 테스트 할 수있는 하나의 시리즈 (1 학생)을 생성

skillmerge = lambda row: ' '.join([str(row.index[i])+':'+str(row[i]) for i in range(0,len(row)) if row[i]!=np.nan]) 

는 람다 함수 내 원하는 형식으로 출력 문자열을 생성하기 위해 초 미만이 소요됩니다. 내가 (다시 테스트 목적) 단 2 행이 dataframe을 만들 때, 함수가 몇 분 그냥 그 2 개 행을 완료하는 데 걸리는 :

testing_df['combined_skills'] = testing_df.apply(skillmerge, axis=1) 

내가 몇이 데이터 집합 만 명 학생을 얼마나로보고를, 이 프로세스를 안정적으로 빠르게 수행 할 수있는 방법을 모색 중입니다. 이 문제를 해결할 수있는 모든 생각?

내 첫 번째 질문에 도움을 미리 감사드립니다! : D

+0

당신은 단지'row.index을 계산할 수있다 [내가]'지능형리스트 전에 라벨이 일정 –

+0

잘 남아 있기 때문에, 그들은 정확히 일정하게 유지되지 않습니다. 원하는 출력 형식에는 평가 점수가없는 기술은 포함되지 않습니다. –

+0

아니요. 그러나 목록의 이해력은''row [i]! = np.nan'에 대해'range (len (indices)) '에있는'i'의 모든 값을 테스트합니다. 따라서 사전에 _every_ 인덱스의 목록을 만들 수 있습니다. 'my_index_list = [skill1, skill2, ... skilln]'그리고'row.index [i]'를'my_index_list [i]'로 변경하십시오. 나에게 왜 런타임이 추가 행을 하나만 추가하면 폭발하는지 분명하지 않습니다. – roganjosh

답변

1

to_json를 사용하여 다음 두 줄

def to_str(x): 
    return x.dropna().to_json(double_precision=0) \ 
      .replace('"', '').replace(',', ' ').strip("{}") 

df.T.apply(to_str) 

또는 목록의 이해와 join

def to_str(x): 
    return " ".join(["{}:{}".format(k, int(v)) for k, v in x.dropna().iteritems()]) 

df.T.apply(to_str) 

를 사용하여 고정

id 
1 skill1:10 skill2:50 skill4:3 
2 skill2:10 skill3:2 skill4:70 
3 skill1:23 skill3:45 skill5:5 
dtype: object 

솔루션 작업 np.nan == np.nanFalse으로 평가하는

skillmerge = lambda row: ' '.join([str(row.index[i])+':'+str(row[i]) for i in range(len(row)) if not np.isnan(row[i])]) 

df.T.apply(skillmerge) 

공지 만들기. np.nan을 테스트하려면 np.isnan 또는 pd.isnull 또는 pd.notnull을 사용하십시오. 이 사실은 당신의 해결책을 던지고있었습니다. 나는 not np.isnan으로 바꿨고 작동합니다.

나는 더 나은 것을 좋아하기 때문에 내가 할 일을 할 수있는 기회를 얻었습니다.

+0

... 그건 멋져, upvote. 이 접근법이 근본적으로 다른 이유에 대해 원래의 접근 방식이 왜 미쳐 가고 있는지에 대해 통찰력을 줄 수 있습니까? 왜'to_json'인가? – roganjosh

+1

@roganjosh 방금 OP 솔루션이 작동하지 않는 이유에 대한 설명으로 게시물을 업데이트했습니다. – piRSquared

+0

@piRSquared 감사합니다. sidnote로, 나의 시스템 모니터는 당신의 접근법이 훨씬 더 효율적인 메모리임을 보여줍니다. –

0

이 시도 :

ld = df.set_index('id').fillna("").to_dict(orient='records') 
ll = [' '.join([ k +":"+ str(v) for k,v in x.iteritems() if v != "" ]) for x in ld ] 
ll 

['skill2:50.0 skill1:10.0 skill4:3.0', 
'skill3:2.0 skill2:10.0 skill4:70.0', 
'skill3:45.0 skill1:23.0 skill5:5.0']