2017-10-22 14 views
1

に輸出のためのパンダのデータフレームを再形成:次データフレームを考えると、ネストされた辞書

Category Area    Country Code Function Last Name  LanID Spend1 Spend2 Spend3 Spend4 Spend5 
0  Bisc EE     RU02,UA02  Mk  Smith df3432  1.0  NaN  NaN  NaN  NaN 
1  Bisc EE      RU02  Mk  Bibs fdss34  1.0  NaN  NaN  NaN  NaN 
2  Bisc EE    UA02,EURASIA  Mk  Crow fdsdr43  1.0  NaN  NaN  NaN  NaN 
3  Bisc WE      FR31  Mk  Ellis fdssdf3  1.0  NaN  NaN  NaN  NaN 
4  Bisc WE     BE32,NL31  Mk  Mower TOZ1720  1.0  NaN  NaN  NaN  NaN 
5  Bisc WE    FR31,BE32,NL31  LKU  Elan SKY8851  1.0  1.0  1.0  1.0  1.0 
6  Bisc SE      IT31  Mk Bobret 3dfsfg  1.0  NaN  NaN  NaN  NaN 
7  Bisc SE      GR31  Mk Concept MOSGX009  1.0  NaN  NaN  NaN  NaN 
8  Bisc SE RU02,IT31,GR31,PT31,ES31  LKU  Solar MSS5723  1.0  1.0  1.0  1.0  1.0 
9  Bisc SE  IT31,GR31,PT31,ES31  Mk  Brix fdgd22  NaN  1.0  NaN  NaN  NaN 
10  Choc CE RU02,CZ31,SK31,PL31,LT31  Fin Ocoser 43233d  NaN  1.0  NaN  NaN  NaN 
11  Choc CE  DE31,AT31,HU31,CH31  Fin  Smuth  4rewf  NaN  1.0  NaN  NaN  NaN 
12  Choc CE    BG31,RO31,EMA  Fin Momocs hgghg2  NaN  1.0  NaN  NaN  NaN 
13  Choc WE    FR31,BE32,NL31  Fin Bruntly ffdd32  NaN  NaN  NaN  NaN  1.0 
14  Choc WE    FR31,BE32,NL31  Mk  Ofer BROGX011  NaN  1.0  1.0  NaN  NaN 
15  Choc WE    FR31,BE32,NL31  Mk  Hem NZJ3189  NaN  NaN  NaN  1.0  1.0 
16  G&C NE     UA02,SE31  Mk  Cre ORY9499  1.0  NaN  NaN  NaN  NaN 
17  G&C NE      NO31  Mk  Qlyo XVM7639  1.0  NaN  NaN  NaN  NaN 
18  G&C NE GB31,NO31,SE31,IE31,FI31  Mk  Omny LOX1512  NaN  1.0  1.0  NaN  NaN 

私はそれが以下の構造で、ネストされた辞書ですにエクスポートを取得したいと思います。だから、基本的に

{RU02: {Bisc: {EE: {Mkt: {Spend1: {df3432: Smith} 
               {fdss34:  Bibs} 
      {Bisc: {SE: {LKU: {Spend1: {MSS5723: Solar} 
            {Spend2: {MSS5723: Solar} 
            {Spend3: {MSS5723: Solar} 
            {Spend4: {MSS5723: Solar} 
            {Spend5: {MSS5723: Solar} 
      {Choc: {CE: {Fin: {Spend2: {43233d: Ocoser} 
      ..... 

    {UA02: {Bisc: {EE: {Mkt: {Spend1: {df3432: Smith} 
               {ffdsdr43: Crow} 
      {G&C: {NE: {Mkt: {Spend1: {ORY9499:  Cre} 
    ..... 

、このDictでは、各CountryCode、LastNames + LandIDs、Per Spendカテゴリ(Spend1、Spend2など)のリストとその属性(Function、Category、Area)を追跡しようとしています。

DataFrameはそれほど大きくはありません(200rows未満)が、カテゴリ/地域/国コードとLastNamesとその支出カテゴリ(多対多)の間のほぼすべてのタイプの組み合わせが含まれています。

私の挑戦は、私がこれまでで考え出し何....私ははっきりと私はDictのへの輸出のために適切にデータフレームを準備するために行うために必要なステップを概念化する方法を見つけ出すことができないんだということ

です私は、必要があること:

  1. 「」区切りに基づく「国コード」欄の内容スライスする方法:DONEを
  2. ユニークな国コードに基づいて新しい列を作成し、それぞれに1を持っていますその列コードがプリセットされている行:DONE
  3. は、再帰的に新しく追加された列
  4. 新しいデータフレームに移動するデータが存在し、それぞれの国コードのために、各列
  5. 輸出Dictsにすべての新しいデータフレームの各データフレームのインデックスを設定し、それらを
  6. をマージ

ステップ3〜6がこれを実行する最善の方法であるかどうかわかりませんが、まだ理解が難しいです。pd.DataFrame.to_dictは私の場合に設定する必要があります...

コーディングの面で非常に感謝していますが、 o各段階の思考プロセスを簡単に説明します。ここで


は私が自分で得た方法遠く..です

#keeping track of initial order of columns 
initialOrder = list(df.columns.values) 

# split the Country Code by "," 
CCodeNoCommas= [item for items in df['Country Code'].values for item in items.split(",")] 

# add only the UNIQUE Country Codes -via set- as new columns in the DataFrame, 
#with NaN for row values 
df = pd.concat([df,pd.DataFrame(columns=list(set(CCodeNoCommas)))]) 

# reordering columns to have the newly added ones at the end 
reordered = initialOrder + [c for c in df.columns if c not in initialOrder] 
df = df[reordered] 


# replace NaN with 1 in the newly added columns (Country Codes), where the same Country code 
# exists in the initial column "Country Code"; do this for each row 

CCodeUniqueOnly = set(CCodeNoCommas) 
for c in CCodeUniqueOnly: 
    CCodeIsPresent_rowIndex = df.index[df['Country Code'].str.contains(c)] 

    #print (CCodeIsPresent_rowIndex) 
    df.loc[CCodeIsPresent_rowIndex, c] = 1 

# no clue what do do next ?? 
+1

これは確かに簡単な解決策ではありません。あなたの努力を示してください。 –

+0

申し訳ありませんが、投稿したときにそれを忘れました。編集されたバージョン@cᴏʟᴅsᴘᴇᴇᴅ – aragalie

答えて

1

あなたのデータフレームを適切なフォーマットに形状を再した場合は、@で答えから便利な再帰的な辞書機能を使用することができますDSMをthis questionに設定します。目標は、各行が一つだけ「エントリ」が含まれているデータフレームを取得することです - あなたが興味を持っている列のユニークな組み合わせを

まず、あなたはリストにあなたの国コード文字列を分割する必要があります。

df['Country Code'] = df['Country Code'].str.split(',') 
this questionからRomanPekarの技術@使用)

そして、複数の行にこれらのリストを展開します。

s = df.apply(lambda x: pd.Series(x['Country Code']),axis=1) \ 
    .stack().reset_index(level=1, drop=True) 
s.name = 'Country Code' 
df = df.drop('Country Code', axis=1).join(s).reset_index(drop=True) 

は、その後、各Spend*列どこの行があります行にSpend*列を再構築することができます値はnanではありません。

spend_cols = ['Spend1', 'Spend2', 'Spend3', 'Spend4', 'Spend5'] 
df = df.groupby('Country Code') \ 
    .apply(lambda g: g.join(pd.DataFrame(g[spend_cols].stack()) \ 
    .reset_index(level=1)['level_1'])) \ 
    .reset_index(drop=True) 

ネストされたディクショナリの各レベルが独自の列であるデータフレームがあります。だから、この再帰的な辞書機能を使用することができます

def recur_dictify(frame): 
    if len(frame.columns) == 1: 
     if frame.values.size == 1: return frame.values[0][0] 
     return frame.values.squeeze() 
    grouped = frame.groupby(frame.columns[0]) 
    d = {k: recur_dictify(g.ix[:,1:]) for k,g in grouped} 
    return d 

をそして唯一のあなたは、彼らが巣をする順番にリストされているネストされた辞書を生成する列に適用します:

べき
cols = ['Country Code', 'Category', 'Area', 'Function', 'level_1', 'LanID', 'Last Name'] 
d = recur_dictify(df[cols]) 

あなたの望む結果を生み出す。


すべてのワンピースで:

df['Country Code'] = df['Country Code'].str.split(',') 
s = df.apply(lambda x: pd.Series(x['Country Code']),axis=1) \ 
    .stack().reset_index(level=1, drop=True) 
s.name = 'Country Code' 
df = df.drop('Country Code', axis=1).join(s).reset_index(drop=True) 

spend_cols = ['Spend1', 'Spend2', 'Spend3', 'Spend4', 'Spend5'] 
df = df.groupby('Country Code') \ 
    .apply(lambda g: g.join(pd.DataFrame(g[spend_cols].stack()) \ 
    .reset_index(level=1)['level_1'])) \ 
    .reset_index(drop=True) 

def recur_dictify(frame): 
    if len(frame.columns) == 1: 
     if frame.values.size == 1: return frame.values[0][0] 
     return frame.values.squeeze() 
    grouped = frame.groupby(frame.columns[0]) 
    d = {k: recur_dictify(g.ix[:,1:]) for k,g in grouped} 
    return d 

cols = ['Country Code', 'Category', 'Area', 'Function', 'level_1', 'LanID', 'Last Name'] 
d = recur_dictify(df[cols]) 
+0

でそれを今すぐ見つけてください!それは完璧に動作し、私は非常にステップの説明によるステップも高く評価します。どうもありがとうございました@ASGM – aragalie

+0

うれしいです。 – ASGM

関連する問題