获取pandas multiindex中的值,并将它们放入列表和多列中

时间:2017-03-17 14:11:13

标签: python pandas

我有使用.extractall()生成的多索引:

                       0       1    2        3    4   5    6    7    8   \
      match
0     0           Leather     NaN  NaN  Leather  NaN NaN  NaN  NaN  NaN
1     0           Leather     NaN  NaN  Leather  NaN NaN  NaN  NaN  NaN
2     0           Leather     NaN  NaN  Leather  NaN NaN  NaN  NaN  NaN
3     0           Leather     NaN  NaN  Leather  NaN NaN  NaN  NaN  NaN
5     0           Leather     NaN  NaN  Leather  NaN NaN  NaN  NaN  NaN
6     0           Leather     NaN  NaN  Leather  NaN NaN  NaN  NaN  NaN
7     0            Canvas  Canvas  NaN      NaN  NaN NaN  NaN  NaN  NaN
8     0            Canvas  Canvas  NaN      NaN  NaN NaN  NaN  NaN  NaN
9     0            Canvas  Canvas  NaN      NaN  NaN NaN  NaN  NaN  NaN
10    0            Canvas  Canvas  NaN      NaN  NaN NaN  NaN  NaN  NaN
11    0           Leather     NaN  NaN  Leather  NaN NaN  NaN  NaN  NaN
12    0            Canvas  Canvas  NaN      NaN  NaN NaN  NaN  NaN  NaN
      1      Calf Leather     NaN  NaN      NaN  NaN NaN  NaN  NaN  NaN
15    0           Leather     NaN  NaN  Leather  NaN NaN  NaN  NaN  NaN
16    0           Leather     NaN  NaN  Leather  NaN NaN  NaN  NaN  NaN
17    0           Leather     NaN  NaN  Leather  NaN NaN  NaN  NaN  NaN
18    0           Leather     NaN  NaN  Leather  NaN NaN  NaN  NaN  NaN
20    0           Leather     NaN  NaN  Leather  NaN NaN  NaN  NaN  NaN

如果查看索引12,则表明此条目有两个匹配," Canvas"和"小牛皮"。如何将此多索引转换为显示所有匹配属性的列?我想知道如何以两种方式做到这一点。这是我想要的第一个结果:

                  material      

0                Leather     
1                Leather     
2                Leather     
3                Leather
4                  Nan      
5                Leather     
6                Leather     
7                 Canvas  
8                 Canvas  
9                 Canvas  
10                Canvas  
11               Leather  
12   Canvas, Calf Leather  
13                 NaN
14                 Nan 
15               Leather  
16               Leather  
17               Leather  
18               Leather
19                 Nan   
20               Leather  

它获取多索引的每个级别的所有结果并将它们转换为列表。您会注意到我只关注原始multiindex中的第0列,这是.extractall的所有结果聚合的地方。这是我想要创建的第二个结果:

                 material     material1 

0                Leather     NaN
1                Leather     NaN
2                Leather     NaN
3                Leather     NaN
4                   NaN      NaN
5                Leather     NaN
6                Leather     NaN
7                 Canvas     NaN
8                 Canvas     NaN
9                 Canvas     NaN
10                Canvas     NaN
11               Leather     NaN
12                Canvas  Calf Leather
13                   NaN     NaN
14                   NaN     NaN
15               Leather     NaN
16               Leather     NaN
17               Leather     NaN
18               Leather     NaN
19                   NaN     NaN
20               Leather     NaN

对于第二个结果,.extractall多指数中匹配最多的列数将会增加。

我很乐意澄清任何不清楚的事情。谢谢!

1 个答案:

答案 0 :(得分:0)

我认为您可以使用dropna删除所有NaN s的列,然后groupby使用汇总join

df1 = df.dropna(axis=1, how='all').groupby(level=0).agg(lambda x: ', '.join(x.dropna()))
#replace to None empty spaces
df1 = df1.replace({'': None})
print (df1)
                       0       1        3

0                Leather    None  Leather
1                Leather    None  Leather
2                Leather    None  Leather
3                Leather    None  Leather
5                Leather    None  Leather
6                Leather    None  Leather
7                 Canvas  Canvas     None
8                 Canvas  Canvas     None
9                 Canvas  Canvas     None
10                Canvas  Canvas     None
11               Leather    None  Leather
12  Canvas, Calf Leather  Canvas     None
15               Leather    None  Leather
16               Leather    None  Leather
17               Leather    None  Leather
18               Leather    None  Leather
20               Leather    None  Leather

对于相同的列长度,使用unstack,然后在MultiIndex列中删除list comprehension

df2 = df.dropna(axis=1, how='all').unstack()
df2.columns = ['mat{}_{}'.format(x[0], x[1]) for x in df2.columns]
print (df2)
     mat0_0        mat0_1  mat1_0 mat1_1   mat3_0 mat3_1

0   Leather          None     NaN   None  Leather   None
1   Leather          None     NaN   None  Leather   None
2   Leather          None     NaN   None  Leather   None
3   Leather          None     NaN   None  Leather   None
5   Leather          None     NaN   None  Leather   None
6   Leather          None     NaN   None  Leather   None
7    Canvas          None  Canvas   None      NaN   None
8    Canvas          None  Canvas   None      NaN   None
9    Canvas          None  Canvas   None      NaN   None
10   Canvas          None  Canvas   None      NaN   None
11  Leather          None     NaN   None  Leather   None
12   Canvas  Calf Leather  Canvas    NaN      NaN    NaN
15  Leather          None     NaN   None  Leather   None
16  Leather          None     NaN   None  Leather   None
17  Leather          None     NaN   None  Leather   None
18  Leather          None     NaN   None  Leather   None
20  Leather          None     NaN   None  Leather   None