2017-09-04 14 views
0

文字列またはリストの要素のセットに変換する要素を持つデータフレームがあり、Noneの場合は空のセットに置き換えます。マスクとエラー/非互換性を使用したデータフレームの型変換

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  

私は2つのステップでそれを行うことができました。そして、それらを使用してステップにこれらのリストを変換し、リスト内の文字列を変換:

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(l)の代わりにそれ以上見つけられない場合は、[]は文字列をそのまま取ります。list()は文字列をその部分に分解します。

次に、set()メソッドを使用してこれらのリストを変換し、Noneを避けるための条件式を変換します(最終目標は列の各行に対して3つのリストを追加することです。私は実際には次のようにコードを使用して、1つのステップでこれを行うことを目的けど、とにかく、私は個人的な啓発のために、以下の質問にお答えしたい)

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 {}) 

が、Pythonはないでしょう私が望むようにしましょう:) 実際にset()メソッドはリストと文字列を受け入れ、li​​st()メソッドのように振る舞います。私はそれを行うために{}を使用することを意図しましたが、うまくいきません。この例外をスロー:

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') 

それはだから私はマスク法は、全体的にベクトル化操作を実行した後に、データを選択するが、このように、これは私にこのエラーをトリガーすると信じています私の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 

だから、私は多分悪い値で始まるようにマスクのように振る舞うが、避けていない同様の機能を使用して、またはこれを変換する別の方法を使用して(1つのステップでこれを行うことができますどのように知っていただきたいと思います)。 なぜリストと[]の動作が違うのか知りたいのですが、これが意図されていることをPythonのドキュメントでは何も見ていないし、set()と{}のidemも見たことがありません。 事前に感謝します。

Quicknote:確か:list_frame2 = list_frame.applymap(ラムダL:設定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} 

編集出力するように、動作しません:データフレーム発生器(しかし、私はそれを行うには、クリップボードからの指示があると思い、それは申し訳ありませんが、私はで最初にそれを含めなかった理由です。

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ならばset()何かを変更しても和がセットでうまく動作しない...) –

答えて

1

あなたはマスキングステップをスキップし、マッピングにまっすぐに行くことができます実際に

。次のような行を導入することで、あなた自身の問題を作成すると感じます。

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

これは、すべてのリストのFalseのマスクを紹介し、そのsuper_graphのほとんどのためのすべての要素が、どのような他の要素のために起こることは、完全に透過的ではありません。

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

EDIT:

は、1行のコードでは、あなたが望むように見えるものを達成するために、あなたのデータフレームに表示されるように、「なし」を希望しない場合は、あなたが最初にこれらの値を置き換えることができます便利なものです。

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でこれを達成できると思います(l l:l *がl以外の場合はll isinstance(l、list)else {l}ならばll)。とにかく、私はリスト(working_series = list_frame.sum(axis = 1))と同じようにセットを集計できないことを知りましたので、リスト上でこれを正確に行い、次にworking_series.map(set)を使用しますそうでなければ、私はリストのすべての罰金ですが、不思議なことに、浮動小数点のみのセットを持っています。あなたが問題に答えたので、私はあなたの答えをとにかく受け入れます。 –

+1

Nonesを取り除きたいなら、 'initial_frame.fillna( '')'を実行できます。軸1上の合計については、 '{'GO3'} {'等の行に沿って恐ろしい結果を生む可能性があります。 – Uvar

+0

ええ、実際には、None部分で間違っていましたが、リストで埋めることができましたが、不可能でしたので、後に置き換えようとしました(文字列の置換は私には起こりませんでした。とにかく置き換えられた文字列)。集計の部分では、集計リストよりも呼び出しを追加しません。なぜなら、セットでは動作しないため、インデックスやラベルを指定したり、ループしたりする必要がない場所で柔軟性を持たせたいからです。だから私はリストで、それは大丈夫だろうと思いますか?毎回アンパックしないと、マスクを使用するよりパフォーマンスが低下する可能性がありますか? –

関連する問題