我有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
转发上一个时间步的填充值。
我可以使用concat
,sort
和ffill
的组合来实现这一目标。
但是,它需要首先重命名其中一个数据帧的列,以便没有名称冲突
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个数据帧到最终合并的多索引数据帧需要采取哪些步骤?
答案 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
然后,您可以添加swaplevel
和sort
来重新组织列,就像第一种方法一样:
df1.append(df2).set_index(['time','id']).sort().unstack().ffill().swaplevel(0,1,axis=1).sort(axis=1)