在新多重索引级别下连接Pandas列

92 投票
3 回答
64788 浏览
提问于 2025-04-18 06:15

假设你有一个字典,里面装着多个数据框,像这样:

dict = {'ABC': df1, 'XYZ' : df2}   # of any length...

每个数据框都有相同的列和类似的索引,比如:

data           Open     High      Low    Close   Volume
Date                                                   
2002-01-17  0.18077  0.18800  0.16993  0.18439  1720833
2002-01-18  0.18439  0.21331  0.18077  0.19523  2027866
2002-01-21  0.19523  0.20970  0.19162  0.20608   771149

那么,最简单的方法是什么,能把所有的数据框合并成一个,并且使用多重索引,像这样:

symbol         ABC                                       XYZ
data           Open     High      Low    Close   Volume  Open ...
Date                                                   
2002-01-17  0.18077  0.18800  0.16993  0.18439  1720833  ...
2002-01-18  0.18439  0.21331  0.18077  0.19523  2027866  ...
2002-01-21  0.19523  0.20970  0.19162  0.20608   771149  ...

我试过几种方法,比如对每个数据框用多重索引替换列,像这样 .from_product(['ABC', columns]),然后沿着 axis=1 进行拼接,但都没有成功。

3 个回答

3

给你的数据框添加一个符号列,并将索引设置为包含这个符号列,然后进行拼接,最后再将这个层级展开:

下面的内容假设你的字典中符号的数量和数据框的数量是一样的,并且你还要确保符号的顺序是你想要的,顺序是根据字典的键来决定的:

DF_dict = {'ABC': df1, 'XYZ' : df2} 
dict_keys = DF_dict.keys()
symbols = ['ABC', 'ZXY']

for x in xrange(len(symbols)):
    DF_dict[dict_keys[x]]['symbol'] = symbols[x]
    DF_dict[dict_keys[x]].reset_index(inplace = True)
    DF_dict[dict_keys[x]].set_index(['symbol', 'Date'], inplace = True)

DF = pd.concat(DF_dict[df] for df in dict_keys)
DF = DF.unstack('symbol')

我觉得这就是我会采取的方法。有些人不喜欢使用 inplace 这种写法。我在这里用它只是为了方便。

6

pandas.concat 现在可以自动完成这个操作:

import pandas as pd

index = ["row1", "row2"]
df_a = pd.DataFrame({"foo": range(0, 2), "bar": range(2, 4)}, index)
df_b = pd.DataFrame({"foo": range(4, 6), "bar": range(6, 8)}, index)

pd.concat({"A": df_a, "B": df_b}, axis=1)  # axis="columns" also works
       A       B    
     foo bar foo bar
row1   0   2   4   6
row2   1   3   5   7
116

你可以使用 concat 来实现这个功能(keys 参数会创建一个层次结构的列索引):

d = {'ABC' : df1, 'XYZ' : df2}
print pd.concat(d.values(), axis=1, keys=d.keys())


                XYZ                                          ABC           \
               Open     High      Low    Close   Volume     Open     High   
Date                                                                        
2002-01-17  0.18077  0.18800  0.16993  0.18439  1720833  0.18077  0.18800   
2002-01-18  0.18439  0.21331  0.18077  0.19523  2027866  0.18439  0.21331   
2002-01-21  0.19523  0.20970  0.19162  0.20608   771149  0.19523  0.20970   


                Low    Close   Volume  
Date                                   
2002-01-17  0.16993  0.18439  1720833  
2002-01-18  0.18077  0.19523  2027866  
2002-01-21  0.19162  0.20608   771149

其实 concat 需要的是列表,所以下面的写法是等价的:

print(pd.concat([df1, df2], axis=1, keys=['ABC', 'XYZ']))

撰写回答