2017-09-04 1 views
0

문자열 또는 목록 인 요소로 변환하려는 요소가있는 데이터 프레임이 있고 없음 인 경우 빈 세트로 바꿉니다.마스크 및 오류/비 호환성을 사용하여 데이터 프레임의 유형 변환

id super_graph sub_graph 
GO1 GO1 ['GO4', 'GO5', 'GO6', 'GO7', 'GO8', 'GO9'] GO9 
GO2 GO2 ['GO4', 'GO5', 'GO6', 'GO7', 'GO8', 'GO9'] GO11 
GO3 GO3 ['GO1', 'GO5', 'GO6', 'GO7', 'GO8', 'GO9'] GO12 
GO4 GO4 ['GO1', 'GO6', 'GO7'] 
GO5 GO5 ['GO5'] 
GO6 GO6 ['GO1', 'GO5', 'GO7', 'GO3', 'GO9'] 
GO7 GO7 ['GO2', 'GO5', 'GO6', 'GO7', 'GO8', 'GO10', 'GO11', 'GO12'] 
GO8 GO8 ['GO2', 'GO3', 'GO4', 'GO5', 'GO6', 'GO7', 'GO8', 'GO9']  
GO9 GO9  

두 단계로 관리 할 수있었습니다. 다음을 사용하여 단계에 해당 목록을 변환 목록에 문자열을 변환 :

initial_frame = count_frame.loc[:,['id', "super_graph", "sub_graph"]]#THE FRAME WHOSE EXAMPLE YOU HAVE ABOVE 
initial_frame_mask = ~initial_frame.applymap(lambda cell: isinstance(cell, list)| (cell is None)) 

list_frame = initial_frame.mask(initial_frame_mask,initial_frame.applymap(lambda l: [l])) 
list_frame2 = list_frame.applymap(lambda l: set(l) if l is not None else {}) 

트릭은 (어쩌면 내가 언어에서 매우 특별한 의미가이 단어를 사용하지 말아야 [] 목록 생성자를 사용하는 것이 여기에있다 하지만 list_frame 생성에서 list (l) 대신에 더 나은 것을 찾을 수는 없습니다. []는 문자열을 취해서 list()가 문자열 시퀀스를 분해합니다.

그런 다음 set() 메서드를 사용하여 이러한 목록을 변환하고 None을 포함하지 않으려면 조건부 표현식을 변환합니다 (최종 목표는 열의 각 행에 세 개의 목록을 추가하는 것입니다. 알고 있지만, 어쨌든, 나는 다음과 같은 코드를 사용하여 실제로 한 단계에서이 작업을 수행하도록

) 개인 교화를 들어, 다음과 같은 것 질문에 응답 할 :

initial_frame = count_frame.loc[:,['id', "super_graph", "sub_graph"]] 
initial_frame_mask = ~initial_frame.applymap(lambda cell: isinstance(cell, list)) 

list_frame = initial_frame.mask(initial_frame_mask,initial_frame.applymap(lambda l: {l}) if l is not None else {}) 

하지만 파이썬은하지 않습니다 내가 원하는대로 할게 :) 실제로 set() 메서드는 목록과 문자열을 받아들이며 list() 메서드처럼 동작합니다. 그래서 그렇게하기 위해 {}을 사용하려고했지만 작동하지 않습니다. 이 예외 던지기 :

In [354]: l=[1,2] 
In [355]: {l} 
Traceback (most recent call last): 

    File "<ipython-input-355-37b01148d270>", line 1, in <module> 
    {l} 

TypeError: unhashable type: 'list' 

그래서 내가 마스크 방법은 전체에 벡터화 작업을 수행 한 후 데이터를 선택 생각하고 정확히

list_frame = initial_frame.mask(initial_frame_mask,initial_frame.applymap(lambda l: {l} if l is not None else {})) 

TypeError: ("unhashable type: 'list'", 'occurred at index super_graph') 

그것은입니다 만, 따라서이이 오류를 유발하는 I 불편한 값을 피하기 위해 initial_frame_mask가 잘 맞춰져 있기 때문에 실제로 보지 말아야한다.

id super_graph sub_graph 
GO1 True False True 
GO2 True False True 
GO3 True False True 
GO4 True False False 
GO5 True False False 
GO6 True False False 
GO7 True False False 
GO8 True False False 
GO9 True False False 

그래서 나는 어쩌면 나쁜 값으로 시작하는 마스크처럼 행동하지만 피하지 않는 유사한 기능을 사용하거나이를 변환하는 다른 방법을 사용하여 (한 번에이 작업을 수행 할 수있는 방법을 알고 싶습니다). 또한 list와 []가 다르게 작동하는 이유를 알고 싶습니다. Python 문서에서 이것이 의도 된 것으로 보이지 않고 set() 및 {}에 대한 idem을 보았습니다. 미리 감사드립니다.

간편 기록 : 참 : list_frame2 = list_frame.applymap (람다 L : 설정 난 중에 {} 밖에되지 없으면 (l))은

id super_graph sub_graph 
GO1 {GO1}  {nan}  {GO9} 
GO2 {GO2}  {nan} {GO11} 
GO3 {GO3}  {nan} {GO12} 
GO4 {GO4}  {nan}  {nan} 
GO5 {GO5}  {nan}  {nan} 
GO6 {GO6}  {nan}  {nan} 
GO7 {GO7}  {nan}  {nan} 
GO8 {GO8}  {nan}  {nan} 
GO9 {GO9}  {nan}  {nan} 

편집 출력으로 작동하지 않을 것 dataframe 발생기 (하지만 난 그렇게 할 수있는 클립 보드에서 명령이 있다고 생각, 그 미안, 내가 처음 그것을 포함하지 않은 이유,

count_frame = pd.DataFrame([["GO2","GO3","GO4","GO5","GO6","GO7","GO8","GO9"],\ 
[["GO4", "GO5","GO6","GO7","GO8","GO9"], 
["GO4", "GO5","GO6","GO7","GO8","GO9"], 
["GO1", "GO5","GO6","GO7","GO8","GO9"], 
["GO1", "GO6","GO7"], 
["GO5"] 
["GO1", "GO5","GO7","GO3","GO9"], 
["GO2", "GO5","GO6","GO7","GO8","GO10","GO11", "GO12"], 
["GO2", "GO3","GO4","GO5","GO6","GO7","GO8","GO9"], 
],\ 
["GO9","GO11","GO12"]], index = ['id','super_graph','sub_graph'], columns=["GO1","GO2","GO3","GO4","GO5","GO6","GO7","GO8","GO9","]).T 
+1

당신이 입력을 생성하는 방법을 제공 할 수 있습니다 (또한 oneliner으로 그것을 할 수 있지만, 이미 충분히 뒤얽힌있다 생각) 고유 항목으로 목록을 얻기에 해키 솔루션 데이터 프레임? 'dtypes'가 무엇인지는 명확하지 않습니다. – IanS

+1

'{l}'대신'{* l}'을 사용해 보셨습니까? – Uvar

+0

그것은 좋은 호칭이 될 것이지만 그것은 끈을 분해 할 것입니다. 어쨌든, 나는 목록을 작성한 다음, 이들을 합하여 다음을 합계했다. (None을 쓰는 경우 None을 쓰고, None을 dicts로 대체하면 None을 쓰지만 None을 쓰면 set()은 ' 아무것도 변경하지 못하고 합계가 집합과 잘 작동하지 않습니다 ...) –

답변

1

당신은 마스킹 단계를 건너 뛰고지도로 바로 갈 수있는 사실

. , 다음 라인을 소개함으로써, 나는 당신이 당신 자신의 문제를 만들었다 고 느낀다.

initial_frame_mask = ~initial_frame.applymap(lambda cell: isinstance(cell, list)) 

은 이처럼 거의 모든 super_graph의 요소,하지만 다른 요소에 발생하는 것은 완전히 투명하지 않은, 모든 목록에 대한 False입니다 마스크를 소개합니다.

initial_frame = count_frame.loc[:,['id', "super_graph", "sub_graph"]] 
initial_frame.applymap(lambda l: {*l} if isinstance(l, list) else {l}) 

편집 :

는 한 줄의 코드에, 당신이 원하는 것 무엇을 달성하기 위해 당신이 당신의 dataframe에 표시하기 위해 "없음"원치 않는 경우, 당신은 첫째로 그 값을 대체 할 수 있습니다 편리한 하나.

initial_frame.fillna('').applymap(lambda l: {*l} if isinstance(l, list) else {l}) 

EDIT2 :

initial_frame['ss'] = initial_frame.fillna('').applymap(lambda l: [*l] if isinstance(l, list) else []).values.sum(axis=1) 
initial_frame['ss'].apply(lambda x: list(filter(None,{*x}))) 
+0

문제는 내가 그들을 없애는 것이 지루할 것이므로 집합에 None을 포함하고 싶지는 않지만 initial_frame.applymap을 사용하여 이것을 달성 할 수 있다고 생각합니다. (lambda l : {l} 만약 l이 존재하지 않는다면, 그렇지 않다. l isinstance (l, list) else {l}이라면). 플러스 어쨌든 나는 내가리스트 (working_series = list_frame.sum (축 = 1))로하는 것과 같은 방식으로 세트를 요약 할 수 없다는 것을 알게되었다. 그래서 목록에서 정확하게 이것을 수행하고 working_series.map (set)을 사용한다. 그렇지 않으면 목록에 모두 괜찮 으면서 이상하게도 떠 다니는 세트 만 있습니다. 어쨌든 당신이 문제를 대답했기 때문에 나는 당신의 대답을 받아 들일 것입니다. –

+1

Nones를 없애기 위해서, 당신은'initial_frame.fillna ('')'를 할 수 있습니다. 축 1에 대한 합계는'{ 'GO3'} {'등의 행을 따라 무서운 결과를 생성하거나 '0'을 그냥 float64로 만듭니다. – Uvar

+0

그래, 실제로 내가 None 부분에 잘못이있어, 목록으로 채우고 싶었지만 불가능 했어. 그래서 나는 그들을 대체하려고했다. (문자열 교체가 나에게 일어나지 않았고, 나는 바보였다. 어쨌든 문자열 대체). 합계 부분에서는 합계 목록보다 더 좋은 호출을 추가하지 않습니다. 세트가 작동하지 않기 때문에 색인이나 레이블을 지정하거나 반복 할 필요가없는 곳에서 유연한 것을 원합니다. 목록으로 보면 괜찮을 것 같네요? 매번 포장을 풀지 않을 경우 마스크를 사용하는 것보다 성능이 현저히 떨어질 수 있습니다. –

관련 문제