2017-03-10 3 views
0

私は、誰かが私の現在のデータフレームをワイドフォーマットからロングフォーマットに変換するのを助けてくれることを願っていました。私はパンダ0.18.0を使用していると私は私の必要性に合うstackoverflow上の他のソリューションを見つけるように見えることはできません。パンダデータフレーム:ワイドからロングへの変換のためにカラムを交互に溶かします

ご協力いただければ幸いです!

私は50種類のステップをそれぞれ2つのカテゴリ(ステータス/時間)で溶かして、これらのカテゴリをデータフレーム内で交互に表示します。 以下はわずか3セットを一例であるが、それは50

状態がいずれであってもよい達するまでこのパターンが継続する:はい/いいえ/ NaNに

時間のいずれかであり得る:タイムスタンプ/ NaNの

現在データフレーム:

 cl_id cl_template_id status-1 time-1      status-2 time-2      status-3 time-3      
0  18434 107   NaN       NaN NaN       NaN NaN       NaN 
1  18280 117   yes  2016-12-28T18:21:58+00:00 yes  2016-12-28T20:47:31+00:00 yes  2016-12-28T20:47:32+00:00 
2  18356 413   yes  2017-01-11T19:23:10+00:00 yes  2017-01-11T19:23:11+00:00 yes  2017-01-11T19:23:11+00:00 
3  18358 430   NaN       NaN NaN       NaN NaN       NaN 
4  18359 430   yes  2017-01-11T19:20:32+00:00 yes  2017-01-11T19:20:34+00:00 NaN       NaN 
. 
. 
. 

ターゲットDATAFRAME:

cl_id cl_template_id step status time 
18434 107    1  NaN  NaN 
18434 107    2  NaN  NaN 
18434 107    3  NaN  NaN 
18280 117    1  yes  2016-12-28T18:21:58+00:00 
18280 117    2  yes  2016-12-28T20:47:31+00:00 
18280 117    3  yes  2016-12-28T20:47:32+00:00 
18356 413    1  yes  2017-01-11T19:23:10+00:00 
18356 413    2  yes  2017-01-11T19:23:11+00:00 
18356 413    3  yes  2017-01-11T19:23:11+00:00 
. 
. 
. 

答えて

0

うまくいけば、この答えは、この問題に対するいくつかの洞察を提供します。

まず、私はあなたのデータフレームからの例を再作成されます:

# Make example dataframe 
df = pd.DataFrame({'cl_id' : [18434, 18280, 18356, 18358, 18359], 
        'cl_template_id' : [107, 117, 413, 430, 430], 
        'status_1' : [np.NaN, 'yes', 'yes', np.NaN, 'yes'], 
        'time_1' : [np.NaN, '2016-12-28T18:21:58+00:00', '2017-01-11T19:23:10+00:00', np.NaN, '2017-01-11T19:20:32+00:00'], 
        'status_2' : [np.NaN, 'yes', 'yes', np.NaN, 'yes'], 
        'time_2' : [np.NaN, '2016-12-28T20:47:31+00:00', '2017-01-11T19:23:11+00:00', np.NaN, '2017-01-11T19:20:34+00:00'], 
        'status_3' : [np.NaN, 'yes', 'yes', np.NaN, np.NaN], 
        'time_3' : [np.NaN, '2016-12-28T20:47:32+00:00', '2017-01-11T19:23:11+00:00', np.NaN, np.NaN]}) 

第二に、日付時刻にtime_1,2,3を変換:

# Convert time_1,2,3 to datetime 
df.loc[:, 'time_1'] = pd.to_datetime(df.loc[:, 'time_1']) 
df.loc[:, 'time_2'] = pd.to_datetime(df.loc[:, 'time_2']) 
df.loc[:, 'time_3'] = pd.to_datetime(df.loc[:, 'time_3']) 

第三に、1〜2にデータフレームを分割

# Split df into a status, time dataframe 
df_status = df.loc[:, :'status_3'] 
df_time = df.loc[:, ['cl_id', 'cl_template_id']].merge(df.loc[:, 'time_1':], 
                 left_index = True, 
                 right_index = True) 

第四に、状況や時間データフレームを溶かす:時間とステータスや他との

# Melt status 
df_status = df_status.melt(id_vars = ['cl_id', 
             'cl_template_id'], 
          value_vars = ['status_1', 
             'status_2', 
             'status_3'], 
          var_name = 'step', 
          value_name = 'status') 

# Melt time 
df_time = df_time.melt(id_vars = ['cl_id', 
            'cl_template_id'], 
         value_vars = ['time_1', 
            'time_2', 
            'time_3'], 
         var_name = 'step', 
         value_name = 'time') 

第五に、数を維持するだけに、両方の状況と時間データフレームの「ステップ」列をクリーンアップ:

# Clean step in status, time 
df_status.loc[:, 'step'] = df_status.loc[:, 'step'].str.partition('_')[2] 
df_time.loc[:, 'step'] = df_time.loc[:, 'step'].str.partition('_')[2] 

第六に、最後のデータフレームに戻って一緒にステータスと時間データフレームをマージ:

# Merge status, time back together on cl_id, cl_template_id 
final = df_status.merge(df_time, 
         how = 'inner', 
         on = ['cl_id', 
           'cl_template_id', 
           'step']).sort_values(by = ['cl_template_id', 
                 'cl_id']).reset_index(drop = True) 

Voila!あなたが探していた答え:

final df

関連する問題