【问题标题】:Converting columns with date in names to separate rows in Python将名称中带有日期的列转换为Python中的单独行
【发布时间】:2019-11-08 13:42:58
【问题描述】:

我已经收到this question in R 的答复,想知道​​如何在 Python 中实现。

假设我们有一个这样的 pandas DataFrame:

import pandas as pd
d = pd.DataFrame({'2019Q1':[1], '2019Q2':[2], '2019Q3':[3]})

显示如下:

   2019Q1  2019Q2  2019Q3
0       1       2       3

我怎样才能把它变成这样:

Year    Quarter    Value
2019    1          1
2019    2          2
2019    3          3

【问题讨论】:

    标签: python pandas data-transform


    【解决方案1】:

    Series.str.split 用于MultiIndexexpand=True,然后通过DataFrame.unstack 进行整形,最后使用Series.reset_indexSeries.rename_axis 进行数据清理:

    d = pd.DataFrame({'2019Q1':[1], '2019Q2':[2], '2019Q3':[3]})
    
    d.columns = d.columns.str.split('Q', expand=True)
    df = (d.unstack(0)
           .reset_index(level=2, drop=True)
           .rename_axis(('Year','Quarter'))
           .reset_index(name='Value'))
    print (df)
       Year Quarter  Value
    0  2019       1      1
    1  2019       2      2
    2  2019       3      3
    

    感谢@Jon Clements 提供另一个解决方案:

    df = (d.melt()
           .variable
           .str.extract('(?P<Year>\d{4})Q(?P<Quarter>\d)')
           .assign(Value=d.T.values.flatten()))
    print (df)
       Year Quarter  Value
    0  2019       1      1
    1  2019       2      2
    2  2019       3      3
    

    替代split:

    df = (d.melt()
           .variable
           .str.split('Q', expand=True)
           .rename(columns={0:'Year',1:'Quarter'})
           .assign(Value=d.T.values.flatten()))
    print (df)
       Year Quarter  Value
    0  2019       1      1
    1  2019       2      2
    2  2019       3      3
    

    【讨论】:

    • 不完全确定,因为它需要测试,但类似:df.melt().variable.str.extract(r'(?P&lt;Year&gt;\d{4})Q(?P&lt;Quarter&gt;\d)').assign(Value=df.values.T) 应该可以解决问题...
    • 好的...快速完成了上述操作,我认为:df.melt().variable.str.extract('(?P&lt;Year&gt;\d{4})Q(?P&lt;Quarter&gt;\d)').assign(Value=df.values.flatten()) 应该这样做:)
    • (这样可以扩展到 > 1 行)
    • @JonClements - 谢谢,在展平之前也需要转置 - d = pd.DataFrame({'2019Q1':[1,8], '2019Q2':[2,9], '2019Q3':[3,0]})
    【解决方案2】:

    DataFrame.stackDataFrame.popSeries.str.split 一起使用:

    df = d.stack().reset_index(level=1).rename(columns={0:'Value'})
    df[['Year', 'Quarter']] = df.pop('level_1').str.split('Q', expand=True)
    
       Value  Year Quarter
    0      1  2019       1
    0      2  2019       2
    0      3  2019       3
    

    如果您关心列的顺序,请使用reindex

    df = df.reindex(['Year', 'Quarter', 'Value'], axis=1)
    
       Year Quarter  Value
    0  2019       1      1
    0  2019       2      2
    0  2019       3      3
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-16
      • 2016-10-17
      相关资源
      最近更新 更多