Python 熊猫从宽到长,但列值作为新列

Python 熊猫从宽到长,但列值作为新列,python,pandas,Python,Pandas,我需要将数据帧从宽转换为长,从这个: country_code category statistic 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 0 AFG Rural Population using at least... 22.0 22

我需要将数据帧从宽转换为长,从这个:

    country_code    category    statistic       2000    2001    2002    2003    2004    2005    2006    2007    2008    2009    2010    2011    2012    2013    2014    2015
0   AFG Rural   Population using at least...    22.0    22.0    23.0    23.0    24.0    25.0    26.0    27.0    27.0    28.0    29.0    30.0    31.0    31.0    32.0    33.0
1   AFG Urban   Population using at least...    31.0    31.0    33.0    35.0    37.0    38.0    40.0    42.0    44.0    46.0    47.0    49.0    51.0    53.0    55.0    56.0
2   ARG Total   Population using at least...    24.0    24.0    25.0    26.0    27.0    28.0    29.0    30.0    31.0    32.0    34.0    35.0    36.0    37.0    38.0    39.0
3   ARG Total   Population using at least...    24.0    24.0    25.0    26.0    27.0    28.0    29.0    30.0    31.0    32.0    34.0    35.0    36.0    37.0    38.0    39.0
4   COL Total   Population using at least...    24.0    24.0    25.0    26.0    27.0    28.0    29.0    30.0    31.0    32.0    34.0    35.0    36.0    37.0    38.0    39.0
我需要一个新的数据框架,它将国家代码、类别和年份作为列值,将统计列中的统计值作为新列,如下所示:

country_code  category year   Population using at least...  Population using safely...
AFG           Rural    2000   22.0                          31.0
AFG           Urban    2001   22.0                          31.0
ARG           Urban    2000   83.0                          80.0
COL           Rural    2000   75.0                          82.0

我一直在使用melt、stack和其他pandas函数,但我无法让它工作。

您可以将数据帧本身熔化,但需要指定
id\u vars
。然后
set_index()
columns,准备在输出中根据需要将最后一列从行转到列。请注意,示例数据框中的“统计列”只有一个唯一字段,但您将在实际数据中看到多个列:

cols = ['country_code', 'category', 'statistic']
df = (df.melt(id_vars=cols, var_name='year', value_name='')
        .set_index(cols+['year'])
        .unstack(2)
        .reset_index())
df.columns = [''.join(col) for col in df.columns] # makes column names clean/single-level
df
Out[1]: 
    country_code   category  year  Population using at least...
0              0  AFG Rural  2000                          22.0
1              0  AFG Rural  2001                          22.0
2              0  AFG Rural  2002                          23.0
3              0  AFG Rural  2003                          23.0
4              0  AFG Rural  2004                          24.0
..           ...        ...   ...                           ...
75             4  COL Total  2011                          35.0
76             4  COL Total  2012                          36.0
77             4  COL Total  2013                          37.0
78             4  COL Total  2014                          38.0
79             4  COL Total  2015                          39.0
准备
unstack()
。索引上必须有两列或更多列。如您所见,使用
set\u index()
后,我们有4个索引:

然后,我们只需将
index=2处的列从行转到列:


您可以将数据帧本身熔化,但需要指定
id\u变量。然后
set_index()
columns,准备在输出中根据需要将最后一列从行转到列。请注意,示例数据框中的“统计列”只有一个唯一字段,但您将在实际数据中看到多个列:

cols = ['country_code', 'category', 'statistic']
df = (df.melt(id_vars=cols, var_name='year', value_name='')
        .set_index(cols+['year'])
        .unstack(2)
        .reset_index())
df.columns = [''.join(col) for col in df.columns] # makes column names clean/single-level
df
Out[1]: 
    country_code   category  year  Population using at least...
0              0  AFG Rural  2000                          22.0
1              0  AFG Rural  2001                          22.0
2              0  AFG Rural  2002                          23.0
3              0  AFG Rural  2003                          23.0
4              0  AFG Rural  2004                          24.0
..           ...        ...   ...                           ...
75             4  COL Total  2011                          35.0
76             4  COL Total  2012                          36.0
77             4  COL Total  2013                          37.0
78             4  COL Total  2014                          38.0
79             4  COL Total  2015                          39.0
准备
unstack()
。索引上必须有两列或更多列。如您所见,使用
set\u index()
后,我们有4个索引:

然后,我们只需将
index=2处的列从行转到列:


首先尝试使用
删除重复的
,然后
堆叠
+
取消堆叠

out = df.drop_duplicates().set_index(['country_code','category','statistic']).stack().unstack(2)

首先尝试使用
drop\u duplicated
,然后尝试
stack
+
unstack

out = df.drop_duplicates().set_index(['country_code','category','statistic']).stack().unstack(2)


请包括图像的样本数据。非常感谢。您的数据在从广域转换为广域后看起来不像long@BENY他之前发布了一张图像,在统计列中有多个值,但在他粘贴的数据中,没有附加值。@DavidErickson第2行和第3行是duplicated@BENY我明白你的意思。我对输入数据也有点困惑。我做了
df=pd。读取剪贴板('\s\s+)
,它在索引列中作为
country\u code
拉入,这使得多索引唯一,因此我可以
取消堆叠
它。请包括图像的样本数据。非常感谢。您的数据在从广域转换为广域后看起来不像long@BENY他之前发布了一张图像,在统计列中有多个值,但在他粘贴的数据中,没有附加值。@DavidErickson第2行和第3行是duplicated@BENY我明白你的意思。我对输入数据也有点困惑。我做了
df=pd。阅读了剪贴板('\s\s+)
,它将索引列作为
country\u code
拉入,这使得多索引独一无二,因此我可以
取消堆叠它。非常感谢!这就是我想做的。我还不明白unstack的部分,以及它是如何使用该参数设置_index的。@IvanParra看到了我发布的两个步骤的图片和说明。这让我过去很困惑。关键的想法是,索引中需要有多个列,这是将其中一个列解压到列的先决条件。我的最新答案解释得更好。我非常感谢你。有了这个形象,一切都很清楚。谢谢师父!非常感谢你!这就是我想做的。我还不明白unstack的部分,以及它是如何使用该参数设置_index的。@IvanParra看到了我发布的两个步骤的图片和说明。这让我过去很困惑。关键的想法是,索引中需要有多个列,这是将其中一个列解压到列的先决条件。我的最新答案解释得更好。我非常感谢你。有了这个形象,一切都很清楚。谢谢师父!我终于理解了
.stack().unstack(2)
的用例。然后您只需要使用
reset_index()
并重命名堆叠的列。谢谢,比融化容易一点。@BENY,太棒了!在一条线之内!非常感谢你!我终于理解了
.stack().unstack(2)
的用例。然后您只需要使用
reset_index()
并重命名堆叠的列。谢谢,比融化容易一点。@BENY,太棒了!在一条线之内!非常感谢你!