2016-10-10 3 views
1

Отрывок из Dateframe может выглядеть следующим образом (это, конечно, гораздо больше):выравнивают ряды по дате в панд dataframe

  Date1  Log1  Date2  Log2 Date3  Log3 
Index 
    0  01.01.2000 1000 02.01.2000 2000 01.01.2000 3000 
    1  02.01.2000 1050 03.01.2000 1950 02.01.2000 3020 
    2  03.01.2000 1100 04.01.2000 2000 03.01.2000 3000 

Есть быстрый способ выравнивания строк так, что даты (здесь в столбцах Date3 и Log3) соответствуют номерам в колонке Date1?

  Date1  Log1  Date2  Log2 Date3  Log3 
Index 
    0  01.01.2000 1000 NaN    01.01.2000 3000 
    1  02.01.2000 1050 02.01.2000 2000 02.01.2000 3020 
    2  03.01.2000 1100 03.01.2000 1950 03.01.2000 3000 

Большое спасибо заранее

+1

Есть намерение, что вы только сохранить значения из [Date2, log2] и [Date3, Log3], которые соответствуют датам в столбце Date1? Другими словами, следует ли полностью отказаться от даты 04.01.2000 с Date2? – andrew

+0

@andrew, нет, дата 04.01.2000 не следует отбрасывать. Индекс длиннее представленных и окончательных дат совпадения всех журналов, но у них разные даты начала. –

ответ

1

Решение с list comprehension и reindex, последние concat все данные вместе:

dates = [col for col in df.columns if 'Date' in col] 
logs = [col for col in df.columns if 'Log' in col] 

print ([df[[col[0], col[1]]].set_index(col[0], drop=False) 
          .reindex(df.Date1) for col in zip(dates, logs)]) 

[     Date1 Log1 
Date1      
01.01.2000 01.01.2000 1000 
02.01.2000 02.01.2000 1050 
03.01.2000 03.01.2000 1100,     Date2 Log2 
Date1       
01.01.2000   NaN  NaN 
02.01.2000 02.01.2000 2000.0 
03.01.2000 03.01.2000 1950.0,     Date3 Log3 
Date1      
01.01.2000 01.01.2000 3000 
02.01.2000 02.01.2000 3020 
03.01.2000 03.01.2000 3000] 

df1 = pd.concat([df[[col[0], col[1]]] 
     .set_index(col[0], drop=False) 
     .reindex(df.Date1) for col in zip(dates, logs)], axis=1) 

df1.reset_index(inplace=True, drop=True) 

print (df1) 
     Date1 Log1  Date2 Log2  Date3 Log3 
0 01.01.2000 1000   NaN  NaN 01.01.2000 3000 
1 02.01.2000 1050 02.01.2000 2000.0 02.01.2000 3020 
2 03.01.2000 1100 03.01.2000 1950.0 03.01.2000 3000 
+0

довольно элегантный, [df [[col [0], col [1]]]. Set_index (col [0], drop = False) .reindex (df.Date1) для col в zip (даты, журналы)] –

+0

Спасибо;) 2 часа работы;) – jezrael

1

Я предполагаю, что вы только хотите сохранить значения из [ «date2», «log2»] и [ «Date3», «LOG3»], когда даты имеют матч в Date1.

Вы можете прочитать разные столбцы в отдельных кадрах данных и использовать merge. Затем фильтруйте только строки, где столбец Date1 не равен NULL.

df 
>>> 
     Date1 Log1  Date2 Log2  Date3 Log3 
0 01.01.2000 1000 02.01.2000 2000 01.01.2000 3000 
1 02.01.2000 1050 03.01.2000 1950 02.01.2000 3020 
2 03.01.2000 1100 04.01.2000 2000 03.01.2000 3000 

df1 = df[['Date1', 'Log1']] 
df2 = df[['Date2', 'Log2']] 
df3 = df[['Date3', 'Log3']] 

df_out = df1.merge(df2, how='outer', left_on='Date1', right_on='Date2') 
df_out = df_out.merge(df3, how='outer', left_on='Date1', right_on='Date3') 
df_out = df_out[df_out['Date1'].notnull()] 

df_out 
>>> 
     Date1 Log1  Date2 Log2  Date3 Log3 
0 01.01.2000 1000.0   NaN  NaN 01.01.2000 3000.0 
1 02.01.2000 1050.0 02.01.2000 2000.0 02.01.2000 3020.0 
2 03.01.2000 1100.0 03.01.2000 1950.0 03.01.2000 3000.0 
1

Словарь для представления ваших данных, это просто удобство загрузки образцов данных в dataframe.

d = {'Date1': {0: '01.01.2000', 1: '02.01.2000', 2: '03.01.2000'}, 'Date3': {0: '01.01.2000', 1: '02.01.2000', 2: '03.01.2000'}, 'Date2': {0: '02.01.2000', 1: '03.01.2000', 2: '04.01.2000'}, 'Log2': {0: 2000, 1: 1950, 2: 2000}, 'Log3': {0: 3000, 1: 3020, 2: 3000}, 'Log1': {0: 1000, 1: 1050, 2: 1100}} 
df = pd.DataFrame(d) 
df = df[['Date1','Log1','Date2','Log2','Date3','Log3']] 
df.index.names = ['Index'] 

print df 

Начиная Dataframe:

  Date1 Log1  Date2 Log2  Date3 Log3 
Index              
0  01.01.2000 1000 02.01.2000 2000 01.01.2000 3000 
1  02.01.2000 1050 03.01.2000 1950 02.01.2000 3020 
2  03.01.2000 1100 04.01.2000 2000 03.01.2000 3000 

Это грубо, но делает работу:

list_dfs = [] 
for i in range(1,4): 
    column_subset = [col for col in df.columns if str(i) in col] 
    df_subset_columns = df[column_subset] 
    df_subset_columns.columns = ['Date','Log'] 
    df_subset_columns['id'] = i 
    list_dfs.append(df_subset_columns) 

df = pd.concat(list_dfs,axis=0,ignore_index=True) 

df = df.set_index(['Date','id']) 
df = df.unstack('id') 
df.columns = df.columns.droplevel(0) 

На данный момент я думаю, что это то, что вы ищете логически:

id    1  2  3 
Date       
01.01.2000 1,000 nan 3,000 
02.01.2000 1,050 2,000 3,020 
03.01.2000 1,100 1,950 3,000 
04.01.2000 nan 2,000 nan 

Но вернуться к нужному выходу

list_dfs = [] 
for i in range(1,4): 
    df_s = df[i].to_frame() 
    df_s.columns = ['Log' + str(i)] 
    print df_s 
    list_dfs.append(df_s.reset_index()) 

print pd.concat(list_dfs,axis=1)