在pandas dataframe中按日期对齐行

时间:2016-10-10 20:11:06

标签: python pandas dataframe

Dateframe的摘录可能看起来像这样(当然要大得多):

            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

是否有快速对齐行的方式,以便日期(此处列Date3Log3)与列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

非常感谢提前

3 个答案:

答案 0 :(得分:1)

我假设您只想在日期与Date1匹配时保留['Date2','Log2']和['Date3','Log3']的值。

您可以将不同的列读入单独的数据框并使用merge。然后过滤以仅保留Date1列不为空的行。

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 :(得分:1)

用于表示数据的字典,这只是将示例数据加载到数据帧的便利。

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)

答案 2 :(得分:1)

使用list comprehensionreindex的解决方案,将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