2017-12-09 9 views
0

私はGEO_IDと、FTYPEごとにGEO_IDと関連する長さが別々の列(6のうち1つ)に属性(FTYPE)を持たないデータフレームを持っています。Python Pandas:merge、join、concat

df 

    FID GEO_ID FTYPE Length_km 

0 1400000US06001400100 428 3.291467766 

1 1400000US06001400100 460 7.566487367 

2 1400000US06001401700 460 0.262190266 

3 1400000US06001401700 566 10.49899202 

4 1400000US06001403300 428 0.138171389 

5 1400000US06001403300 558 0.532913513 
私は(その行がFTYPEを持っているかどうかを示すために1と0で)FTYPEための6つの新しい列を作成するにはどうすればよい

とFTYPE_Lengthのための6つの新しい列、各行が一意GEO_IDを持って作るには?

私は(6 FTYPE-Sで)このような構造を持っている私の新しいデータフレームをしたい:

import pandas as pd 
fname = "filename.csv" 
df = pd.read_csv(fname) 
nhd = [334, 336, 420, 428, 460, 558, 556] 
df1 = df.loc[df['FTYPE']==nhd[0]] 
df2 = df.loc[df['FTYPE']==nhd[1]] 
df3 = df.loc[df['FTYPE']==nhd[2]] 
df4 = df.loc[df['FTYPE']==nhd[3]] 
df5 = df.loc[df['FTYPE']==nhd[4]] 
df6 = df.loc[df['FTYPE']==nhd[5]] 
df7 = df.loc[df['FTYPE']==nhd[6]] 
df12 = df1.merge(df2, how='left', left_on='GEO_ID', right_on='GEO_ID') 
df23 = df12.merge(df3,how='left', left_on='GEO_ID', right_on='GEO_ID') 
df34 = df23.merge(df4,how='left', left_on='GEO_ID', right_on='GEO_ID') 
df45 = df34.merge(df5,how='left', left_on='GEO_ID', right_on='GEO_ID') 
df56 = df45.merge(df6,how='left', left_on='GEO_ID', right_on='GEO_ID') 
df67 = df56.merge(df7,how='left', left_on='GEO_ID', right_on='GEO_ID') 
cols = [0,4,7,10,13,16,19] 
df67.drop(df67.columns[cols],axis=1,inplace=True) 
df67.columns =['GEO_ID','334','len_334','336','len_336','420','len_420','428','len_428','460','len_460','558','len_558','566','len_566'] 

FID GEO_ID FTYPE_428 FTYPE_428_length FTYPE_460 FTYPE_460_length 
0 1400000US06001400100 1 3.291467766 1 7.566487367 

これまでのところ、私が試してみましたがこのような何かをやっていますしかし、最初の2つのFTYPEを持つものに行を減らすため、このアプローチは問題になります。一度に複数の列をマージする方法はありますか?

ループのために書くと、各行の上に行くと、このような値を入力するために条件を使用した方が簡単でしょその:

nhd = [334, 336, 420, 428, 460, 558, 556] 
for x in nhd: 
    df[str(x)] = None 
    df["length_"+str(x)] = None 
df.head() 
for geoid in df["GEO_ID"]: 
    #print geoid 
    for x in nhd: 
     df.ix[(df['FTYPE']==x) & (df['GEO_ID'] == geoid)][str(nhd)] = 1 

しかし、これはあまりにも多くの時間がかかり、1つのライナーは、おそらくそこにありますパンダも同じことをする。

これに関するお手伝いがあります。

おかげで、 ソロモン

答えて

1

は、私はかなりあなたの_length列のポイントが表示されていない。彼らは、彼らが冗長になりた、としてちょうど一致する値がnullであるか否か、同じ情報を持っているように思われます。彼らは、しかし、作成するのは簡単です。

私たちが主張すれば、これを1行にすることができますが、何がポイントですか?これはコードゴルフではなくSOです。

In [49]: final 
Out[49]: 
         FTYPE_334 FTYPE_334_length FTYPE_428 \ 
GEO_ID               
1400000US06001400100  NaN     0 3.291468 
1400000US06001401700  NaN     0  NaN 
1400000US06001403300  NaN     0 0.138171 
1400000US06001403400 0.04308     1  NaN 

         FTYPE_428_length FTYPE_460 FTYPE_460_length \ 
GEO_ID                 
1400000US06001400100     1 7.566487     1 
1400000US06001401700     0 0.262190     1 
1400000US06001403300     1  NaN     0 
1400000US06001403400     0  NaN     0 

         FTYPE_558 FTYPE_558_length FTYPE_566 FTYPE_566_length 
GEO_ID                   
1400000US06001400100  NaN     0  NaN     0 
1400000US06001401700  NaN     0 10.498992     1 
1400000US06001403300 0.532914     1 1.518864     1 
1400000US06001403400  NaN     0  NaN     0 
+0

グレート:(唯一の5つの異なるFTYPEsを持っている、あなたの入力データを使用して)私を与え

df = df.pivot(index="GEO_ID", columns="FTYPE", values="Length_km") df.columns = "FTYPE_" + df.columns.astype(str) has_value = df.notnull().astype(int) has_value.columns += '_length' final = pd.concat([df, has_value], axis=1).sort_index(axis='columns') 

:だから私のような何かを行う可能性があります!迅速な答えをありがとう。あなたが正しいです、情報が冗長であるため、長さの列を削除することができます。 – solonome