创建具有分层列的DataFrame
的最简单方法是什么?
我目前正在使用从dict of names->Series
创建一个DataFrame
df = pd.DataFrame(data=serieses)
我想使用相同的列名,但在列上添加一个额外的层次结构级别。目前,我希望附加级别对列具有相同的值,比如说"估计"。
我正在尝试以下操作,但似乎不起作用:
pd.DataFrame(data=serieses,columns=pd.MultiIndex.from_tuples([(x, "Estimates") for x in serieses.keys()]))
我得到的只是一个包含所有NaN的DataFrame。
例如,我要找的大致是:
l1 Estimates
l2 one two one two one two one two
r1 1 2 3 4 5 6 7 8
r2 1.1 2 3 4 5 6 71 8.2
其中l1和l2是多索引的标签
这似乎有效:
import pandas as pd
data = {'a': [1,2,3,4], 'b': [10,20,30,40],'c': [100,200,300,400]}
df = pd.concat({"Estimates": pd.DataFrame(data)}, axis=1, names=["l1", "l2"])
l1 Estimates
l2 a b c
0 1 10 100
1 2 20 200
2 3 30 300
3 4 40 400
我知道这个问题很老,但对于pandas
版本0.19.1
,可以使用直接dict初始化:
d = {('a','b'):[1,2,3,4], ('a','c'):[5,6,7,8]}
df = pd.DataFrame(d, index=['r1','r2','r3','r4'])
df.columns.names = ('l1','l2')
print df
l1 a
l2 b c
r1 1 5
r2 2 6
r3 3 7
r4 4 8
我不确定,但我认为使用dict作为DF的输入和MulitIndex在一起不太好。相反,使用数组作为输入可以使其工作。
不过,我通常更喜欢dicts作为输入,一种方法是在创建df:之后设置列
import pandas as pd
data = {'a': [1,2,3,4], 'b': [10,20,30,40],'c': [100,200,300,400]}
df = pd.DataFrame(np.array(data.values()).T, index=['r1','r2','r3','r4'])
tups = zip(*[['Estimates']*len(data),data.keys()])
df.columns = pd.MultiIndex.from_tuples(tups, names=['l1','l2'])
l1 Estimates
l2 a c b
r1 1 10 100
r2 2 20 200
r3 3 30 300
r4 4 40 400
或者当使用数组作为df:的输入时
data_arr = np.array([[1,2,3,4],[10,20,30,40],[100,200,300,400]])
tups = zip(*[['Estimates']*data_arr.shape[0],['a','b','c'])
df = pd.DataFrame(data_arr.T, index=['r1','r2','r3','r4'], columns=pd.MultiIndex.from_tuples(tups, names=['l1','l2']))
这给出了相同的结果。
Rutger Kassies的解决方案在我的案例中起了作用,但我在";上层";列层次结构的。只是想提供一个对我有效的例子,因为这是一个更普遍的情况。
首先,我有这样的数据:
> df
(A, a) (A, b) (B, a) (B, b)
0 0.00 9.75 0.00 0.00
1 8.85 8.86 35.75 35.50
2 8.51 9.60 66.67 50.70
3 0.03 508.99 56.00 8.58
我希望它看起来像这样:
> df
A B
a b a b
0 0.00 9.75 0.00 0.00
1 8.85 8.86 35.75 35.50
...
解决方案是:
tuples = df.transpose().index
new_columns = pd.MultiIndex.from_tuples(tuples, names=['Upper', 'Lower'])
df.columns = new_columns
这是违反直觉的,因为为了创建列,我必须通过索引来完成。