取消堆叠或仅转动某些列

时间:2015-10-10 19:13:34

标签: python pandas

鉴于以下数据框:

import pandas as pd
DF = pd.DataFrame({'COL1': ['A', 'A', 'A', 'B','B','B'], 
                   'COL2' : [1,2,3,1,2,3],
                   'COL3': [11032, 1960, 11400, 11355, 8, 7], 
                   'year': ['2016', '2017', '2018', '2019', '2020', '2021']})
DF

        COL1 COL2 COL3  COL4    year
     0    A   1   2    11032    2016
     1    A   2   2    1960     2017
     2    A   3   4    11400    2018
     3    B   1   2    11355    2019
     4    B   2   2    8        2020
     5    B   3   4    7        2021

我只想通过COL1拆开“COL4”和“Year”,同时保持COL2和COL3的机智。最终结果应如下所示:

    COL2    COL3    COL4 (A)    year (A)    COL4 (B)    year (B)
0      1     2     11032       2016         11355       2019
1      2     2     1960        2017         8           2020
2      3     4     11400       2018         7           2021

另外,如果在“COL1”下有一些没有“A”的记录怎么办?

我假设解决方案将在取消堆叠时查找与“COL2”和“COL3”匹配的记录(如果这是使用的方法)。 通过这种方式,我的意思是如果列的顺序没有像我的例子那样排序,它将产生相同的结果。

谢谢!

1 个答案:

答案 0 :(得分:1)

您可以按前3列设置多索引,并将unstacklevel=0一起使用 然后,您可以重命名列名称 - 或levelslabels或自定义名称。

#  COL1  COL2  COL3   COL4  year
#0    A     1     2  11032  2016
#1    A     2     2   1960  2017
#2    A     3     4  11400  2018
#3    B     1     2  11355  2019
#4    B     2     2      8  2020
#5    B     3     4      7  2021

DF = DF.set_index(['COL1', 'COL2', 'COL3'])
DF = DF.unstack(0).reset_index()
print DF
#     COL2 COL3   COL4         year
#COL1                A      B     A     B
#0       1    2  11032  11355  2016  2019
#1       2    2   1960      8  2017  2020
#2       3    4  11400      7  2018  2021

levels = DF.columns.levels
labels = DF.columns.labels
DF.columns = levels[0][labels[0]]
print DF
#   COL2  COL3   COL4   COL4  year  year
#0     1     2  11032  11355  2016  2019
#1     2     2   1960      8  2017  2020
#2     3     4  11400      7  2018  2021
DF.columns = ['COL2','COL3','COL4','COL5','COL6','COL7']
print DF
#   COL2  COL3   COL4   COL5  COL6  COL7
#0     1     2  11032  11355  2016  2019
#1     2     2   1960      8  2017  2020
#2     3     4  11400      7  2018  2021

但如果列COL2COL3的顺序不同,您可以使用Andy Hayden的little hack

#  COL1  COL2  COL3   COL4  year
#0    A     4     6  11032  2016
#1    A     9     2   1960  2017
#2    A     8     4  11400  2018
#3    B     4     6  11355  2019
#4    B     9     2      8  2020
#5    B     8     4      7  2021
DF = DF.set_index(['COL1', 'COL2', 'COL3'])

index = pd.MultiIndex(levels=[DF.index.get_level_values(1).unique(),
                   DF.index.get_level_values(2).unique()],
                   labels=[[0, 1, 2],
                   [0, 1, 2]])
DF = DF.unstack(0)
DF = DF.reindex(index).reset_index()
print DF
#     level_0 level_1   COL4         year
#COL1                      A      B     A     B
#0          4       6  11032  11355  2016  2019
#1          9       2   1960      8  2017  2020
#2          8       4  11400      7  2018  2021
levels = DF.columns.levels
labels = DF.columns.labels
DF.columns = levels[0][labels[0]]
print DF
#   level_0  level_1   COL4   COL4  year  year
#0        4        6  11032  11355  2016  2019
#1        9        2   1960      8  2017  2020
#2        8        4  11400      7  2018  2021
DF.columns = ['COL2','COL3','COL4','COL5','COL6','COL7']
print DF
#   COL2  COL3   COL4   COL5  COL6  COL7
#0     4     6  11032  11355  2016  2019
#1     9     2   1960      8  2017  2020
#2     8     4  11400      7  2018  2021