【问题标题】:Pivot Tables on pythonpython上的数据透视表
【发布时间】:2019-09-27 13:00:31
【问题描述】:

我有一个带有数据表的 csv。我想读取 csv 并根据初始 csv 编写一个新的 xlsx 文件。

但是,我还想添加一个新列,该列将具有基于标题名称的值(例如,如果标题包含在线单词)并基于此逻辑创建某种数据透视表。因此,与使用三列线索相反,我将一列由三行表示(每列)

date    online_won    retail_won     outbound_won    online_leads   retail_leads     outbound_leads
1/1/11     9            10              11             12             14
2/1/11     1            2               13             15
3/1/11     10           8               14             17

这是想要的输出

date      source   won    leads
1/1/11    online    9       12
1/1/11    retail   10       14
1/1/11    outbound 11       
.....

我假设我可以使用 pd.pivot_table 解决这个问题。但无法弄清楚如何将列返回为 won 和 Lead,并仅从现有列中提取 online/retail/outbound 部分。

【问题讨论】:

    标签: python pandas pivot-table


    【解决方案1】:

    您可以使用pd.wide_to_long,在列上做一些额外的工作,因为假设宽格式变量以存根名称开头​​:

    df.columns = ['_'.join(j for j in i[::-1]) for i in df.columns.str.split('_')]
    (pd.wide_to_long(df, stubnames=['won','leads'], i='date', j='source', suffix='_\w+')
       .reset_index())
    
        date     source   won  leads
    0  1/1/11    _online    9   12.0
    1  2/1/11    _online    1   15.0
    2  3/1/11    _online   10   17.0
    3  1/1/11    _retail   10   14.0
    4  2/1/11    _retail    2    NaN
    5  3/1/11    _retail    8    NaN
    6  1/1/11  _outbound   11    NaN
    7  2/1/11  _outbound   13    NaN
    8  3/1/11  _outbound   14    NaN
    

    【讨论】:

    • 这正是我的解决方案:-)。
    • 哈!似乎我们在那里有相同的思考过程:) @quang
    【解决方案2】:

    通过列重命名,您可以使用wide_to_long

    df.columns = ['_'.join(x.split('_')[::-1]) for x in df.columns ]
    pd.wide_to_long(df, ['won','leads'], 'date', 'source', sep='_', suffix='\w+')
    

    输出:

                     won  leads
    date   source              
    1/1/11 online      9   12.0
    2/1/11 online      1   15.0
    3/1/11 online     10   17.0
    1/1/11 retail     10   14.0
    2/1/11 retail      2    NaN
    3/1/11 retail      8    NaN
    1/1/11 outbound   11    NaN
    2/1/11 outbound   13    NaN
    3/1/11 outbound   14    NaN
    

    【讨论】:

    • 不错的一个.. 比我的这个用例更好
    【解决方案3】:

    meltseries.str.split()unstack() 一起使用的另一种方式`:

    m=df.melt('date').sort_values('date')
    m[['Source','Status']]=m.pop('variable').str.split('_',expand=True)
    final=(m.set_index(['date','Source','Status']).unstack()
                 .droplevel(0,axis=1).reset_index().rename_axis(None,axis=1))
    

         date    Source  leads   won
    0  1/1/11    online   12.0   9.0
    1  1/1/11  outbound    NaN  11.0
    2  1/1/11    retail   14.0  10.0
    3  2/1/11    online   15.0   1.0
    4  2/1/11  outbound    NaN  13.0
    5  2/1/11    retail    NaN   2.0
    6  3/1/11    online   17.0  10.0
    7  3/1/11  outbound    NaN  14.0
    8  3/1/11    retail    NaN   8.0
    

    【讨论】:

      【解决方案4】:

      DataFrame.set_indexstr.split 一起用于MultiIndex,因此可以通过第一级DataFrame.stack 0

      df = df.set_index('date')
      df.columns = df.columns.str.split('_', expand=True)
      df = df.stack(0).rename_axis(('date','Source')).reset_index()
      print (df)
           date    Source  leads  won
      0  1/1/11    online   12.0    9
      1  1/1/11  outbound    NaN   11
      2  1/1/11    retail   14.0   10
      3  2/1/11    online   15.0    1
      4  2/1/11  outbound    NaN   13
      5  2/1/11    retail    NaN    2
      6  3/1/11    online   17.0   10
      7  3/1/11  outbound    NaN   14
      8  3/1/11    retail    NaN    8
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-10-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-23
        • 2018-04-10
        • 2021-12-30
        相关资源
        最近更新 更多