pandas:在列数据上连接数据帧,前向填充和多索引

时间:2015-05-14 04:05:23

标签: python pandas

我有2个csv文件具有相同的列名,但值不同。

第一列是索引(time),其中一个数据列是唯一标识符(id

每个csv文件的索引(time)都不同。

我已使用read_csv将数据读入2个数据框,并提供以下内容:

        +-------+------+-------+
        | id    | size | price |
+-------+-------+------+-------+
| time  |       |      |       |
+-------+-------+------+-------+
| t0    | ID1   | 10   | 110   |
| t2    | ID1   | 12   | 109   |
| t6    | ID1   | 20   | 108   |
+-------+-------+------+-------+

        +-------+------+-------+
        | id    | size | price |
+-------+-------+------+-------+
| time  |       |      |       |
+-------+-------+------+-------+
| t1    | ID2   |  9   |  97   |
| t3    | ID2   | 15   |  94   |
| t5    | ID2   | 13   | 100   |
+-------+-------+------+-------+

我想创建一个包含两个条目的大型数据框,并使用ffill转发上一个时间步的填充值。

我可以使用concatsortffill的组合来实现这一目标。

但是,它需要首先重命名其中一个数据帧的列,以便没有名称冲突

df2.columns = [ 'id', 'id2_size', 'id2_price' ]
df = pd.concat([df1, df2]).sort().ffill()

这导致以下数据帧:

        +------+------+-------+----------+-----------+
        | id   | size | price | id2_size | id2_price |
+-------+------+------+-------+----------+-----------+
| time  |      |      |       |          |           |
+-------+------+------+-------+----------+-----------+
| t0    | ID1  | 10   | 110   |     nan  |     nan   |
| t1    | ID2  | 10   | 110   |      9   |      97   |
| t2    | ID1  | 12   | 109   |      9   |      97   |
| t3    | ID2  | 12   | 109   |     15   |      94   |
| t5    | ID2  | 12   | 109   |     13   |     100   |
| t6    | ID1  | 20   | 108   |     13   |     100   |
+-------+------+------+-------+----------+-----------+

我当前的方法相当笨重,因为我必须重命名其中一个数据帧的列。

我认为更好的表示数据的方法是使用multiindex,其中第二维的值来自id列。

结果数据框如下所示:

        +--------------+--------------+
        | ID1          | ID2          |
        +------+-------+------+-------+
        | size | price | size | price |
+-------+------+-------+------+-------+
| time  |      |       |      |       |
+-------+------+-------+------+-------+
| t0    | 10   | 110   | nan  | nan   |
| t1    | 10   | 110   |  9   |  97   |
| t2    | 12   | 109   |  9   |  97   |
| t3    | 12   | 109   | 15   |  94   |
| t5    | 12   | 109   | 13   | 100   |
| t6    | 20   | 108   | 13   | 100   |
+-------+------+-------+------+-------+

这可能吗?
如果是这样,从csv读取的2个数据帧到最终合并的多索引数据帧需要采取哪些步骤?

1 个答案:

答案 0 :(得分:1)

这是一个可以满足您要求的单线程,虽然它在堆叠/卸载方面有点复杂:

df1.append(df2).set_index(['time','id']).sort().stack().unstack(level=[1,2]).ffill()

id    ID1        ID2      
     size price size price
time                      
t0     10   110  NaN   NaN
t1     10   110    9    97
t2     12   109    9    97
t3     12   109   15    94
t5     12   109   13   100
t6     20   108   13   100

FWIW,我的默认方法类似于以下内容,它更直接(更少堆叠/卸载)并且会给你相同的基本结果,但是具有不同的列组织:

df1.append(df2).set_index(['time','id']).sort().unstack().ffill()

     size     price     
id    ID1 ID2   ID1  ID2
time                    
t0     10 NaN   110  NaN
t1     10   9   110   97
t2     12   9   109   97
t3     12  15   109   94
t5     12  13   109  100
t6     20  13   108  100

然后,您可以添加swaplevelsort来重新组织列,就像第一种方法一样:

df1.append(df2).set_index(['time','id']).sort().unstack().ffill().swaplevel(0,1,axis=1).sort(axis=1)