【问题标题】:Convert Pandas Dataframe from Row based to Columnar将 Pandas 数据框从基于行转换为列
【发布时间】:2016-09-17 18:10:13
【问题描述】:

我的数据框 (df) 如下所示:

Date       FieldA  ValueA ValueB
09-02-2016 TypeA   3       5
09-02-2016 TypeB   6       7

我希望数据框如下所示:

Date       TypeA_ValueA   TypeA_ValueB  TypeB_ValueA TypeB_ValueB
09-02-2016  3             5             6            7

我厌倦了 pandas 中的 df.pivot,我可以在其中提供单个值列。它不需要超过一个。当我提供多个时,我得到以下异常。 pandas_pivot

Exception: Data must be 1-dimensional

【问题讨论】:

    标签: python sql pandas pyspark spark-dataframe


    【解决方案1】:
    df1 = df.set_index(['Date', 'FieldA']).unstack()
    df1.columns = df1.columns.map('_'.join)
    
    df1.reset_index()
    


    设置参考

    from StringIO import StringIO
    import pandas as pd
    
    text = """Date       FieldA  ValueA ValueB
    09-02-2016 TypeA   3       5
    09-02-2016 TypeB   6       7"""
    
    df = pd.read_csv(StringIO(text), delim_whitespace=True)
    
    df
    

    【讨论】:

    • 出现错误:TypeError:序列项 0:预期字符串,找到 int
    • 现在出现新错误 AttributeError: 'Series' object has no attribute 'columns'
    【解决方案2】:
    In [36]: df
    Out[36]: 
            Date FieldA  ValueA  ValueB
    0 2016-09-02  TypeA       3       5
    1 2016-09-02  TypeB       6       7
    2 2016-09-03  TypeA       4       8
    3 2016-09-03  TypeB       3       9
    
    In [37]: v_cols = df.columns.difference(['FieldA', 'Date'])
    
    In [38]: def func(x):
         ...:     d = {'_'.join([t, c]): x[x['FieldA'] == t][c].iloc[0] for t in x.FieldA for c in v_cols}
         ...:     for k, v in d.iteritems():
         ...:         x[k] = v
         ...:     return x
         ...: 
    
    In [39]: newdf = df.groupby('Date').apply(func)
    
    In [40]: newdf.drop(v_cols.tolist() + ['FieldA'], axis=1).drop_duplicates()
    Out[340]: 
            Date  TypeA_ValueA  TypeA_ValueB  TypeB_ValueA  TypeB_ValueB
    0 2016-09-02             3             5             6             7
    2 2016-09-03             4             8             3             9
    

    【讨论】:

      【解决方案3】:

      使用pd.pivot_table

      In [1]: pd.pivot_table(df, index='Date', columns='FieldA', values=['ValueA', 'ValueB'])
      Out[1]: 
                 ValueA       ValueB      
      FieldA      TypeA TypeB  TypeA TypeB
      Date                                
      09-02-2016      3     6      5     7
      

      因此,您将获得一个带有 MultiIndex 的 DataFrame。如果您想将其展平并在列名中使用 _ 作为分隔符,您可以这样做:

      In [1]: df = pd.pivot_table(df, index='Date', columns='FieldA', values=['ValueA', 'ValueB'])
      
      In [2]: df.columns = [ '{}_{}'.format(cat, val) for val, cat in df.columns ]
      
      In [3]: df
      Out[3]: 
                  TypeA_ValueA  TypeB_ValueA  TypeA_ValueB  TypeB_ValueB
      Date                                                              
      09-02-2016             3             6             5             7
      

      【讨论】:

      • 得到错误 pandas.core.groupby.DataError: No numeric types to aggregate... 虽然我已经转换了数据类型
      • 可能您使用了错误的参数顺序(在我提供的示例中,使用了命名参数)。 pandas.pydata.org/pandas-docs/stable/generated/… 如果您想使用位置参数,只需将它们重新排序为值在前。是这样吗?
      • 啊...抱歉,我发布了错误的错误消息实际错误我在第二行中提到了如何展平df。错误是 ValueError: too many value to unpack。在我原来的 df 中,我在字段 A 中有 35 行和 5 个值列
      猜你喜欢
      • 2018-03-25
      • 1970-01-01
      • 1970-01-01
      • 2017-06-22
      • 1970-01-01
      • 2017-04-01
      • 2018-07-27
      • 2021-03-22
      • 2020-09-02
      相关资源
      最近更新 更多