2017-10-25 45 views
1

私は以下の問題を解決する良い方法を模索しています。私の現在の修正は特にきれいではなく、あなたの洞察から学びたいと思っています。Pandas DataFrameの列リストを分割する

が、私はそのエントリが次のようになりパンダのデータフレームを、持っているとします

>>> df=pd.DataFrame(index=[1,2,3],columns=['Color','Texture','IsGlass']) 

>>> df['Color']=[np.nan,['Red','Blue'],['Blue', 'Green', 'Purple']] 
>>> df['Texture']=[['Rough'],np.nan,['Silky', 'Shiny', 'Fuzzy']] 
>>> df['IsGlass']=[1,0,1] 

>>> df 
          Color     Texture IsGlass 
    1       NaN     ['Rough']  1 
    2    ['Red', 'Blue']      NaN  0 
    3 ['Blue', 'Green', 'Purple'] ['Silky','Shiny','Fuzzy']  1 

だから、インデックス内の各観測は、私はその色、質感、そしてそれはガラスだかいないかどうかについて測定されたものに対応しています。私がしたいことは、観測値ごとに列を作成し、それが観測された場合は対応するエントリを変更し、情報がない場合はNaNに変更することで、これを新しい「指標」DataFrameにします。

>>> df 
     Red Blue Green Purple Rough Silky Shiny Fuzzy Is Glass    
    1 Nan Nan Nan Nan 1  NaN Nan Nan  1   
    2  1 1 Nan Nan Nan Nan Nan Nan  0 
    3 Nan 1 1  1  Nan 1  1  1  1 

私は、各列をループソリューションを持ってその値を見て、非NaN値に努め/ exceptsでの一連の、リストを分割し、新しい列などを作成し、連結します。

これは私の最初の投稿StackOverflowです - 私はこの投稿が掲載ガイドラインに準拠していることを願っています。ありがとう。

+0

を使用していますか?または['Blue'、 'Green'、 'Purple'] – Wen

+0

ありがとうございます。それは['Blue'、 'Green'、 'Purple']です。それに応じて編集します。 –

+0

私のソリューションを追加〜:-) – Wen

答えて

3

スタッキングハッキング!

from sklearn.preprocessing import MultiLabelBinarizer 

mlb = MultiLabelBinarizer() 

df = df.stack().unstack(fill_value=[]) 

def b(c): 
    d = mlb.fit_transform(c) 
    return pd.DataFrame(d, c.index, mlb.classes_) 

pd.concat([b(df[c]) for c in ['Color', 'Texture']], axis=1).join(df.IsGlass) 

    Blue Green Purple Red Fuzzy Rough Shiny Silky IsGlass 
1  0  0  0 0  0  1  0  0  1 
2  1  0  0 1  0  0  0  0  0 
3  1  1  1 0  1  0  1  1  1 
+0

'MultiLabelBinarizer'を使用しているのは速度ですか? – Wen

+0

@Wen最初に頭に浮かんだこととオプションを提供する時間がありません – piRSquared

+0

それを得ました:-) LOL! – Wen

1

各行のテクスチャ/カラーごとに、値がnullかどうかを確認します。そうでない場合、その行の列= 1としてその値を追加します。

import numpy as np 
import pandas as pd 

df=pd.DataFrame(index=[1,2,3],columns=['Color','Texture','IsGlass']) 

df['Color']=[np.nan,['Red','Blue'],['Blue', 'Green', 'Purple']] 
df['Texture']=[['Rough'],np.nan,['Silky', 'Shiny', 'Fuzzy']] 
df['IsGlass']=[1,0,1] 

for row in df.itertuples(): 

    if not np.all(pd.isnull(row.Color)): 
     for val in row.Color: 
      df.loc[row.Index,val] = 1  

    if not np.all(pd.isnull(row.Texture)): 
     for val in row.Texture: 
      df.loc[row.Index,val] = 1 
+0

あなたの答えをありがとう、私はそれから多くを学んだ! –

1

私はちょうどあなたのデータ形式は文字列またはリストのですか?[ 'ブルー、グリーン、パープル'] pandasget_dummies

l=[pd.get_dummies(df[x].apply(pd.Series).stack(dropna=False)).sum(level=0) for x in ['Color','Texture']] 
pd.concat(l,axis=1).assign(IsGlass=df.IsGlass) 
Out[662]: 
    Blue Green Purple Red Fuzzy Rough Shiny Silky IsGlass 
1  0  0  0 0  0  1  0  0  1 
2  1  0  0 1  0  0  0  0  0 
3  1  1  1 0  1  0  1  1  1 
+0

あなたの答えをありがとう、私はそれから多くを学んだ! –

+0

@AdamAzzam Yw〜おやすみなさい – Wen

関連する問題