【问题标题】:Is there a pandas function to transpose a data frame to create a separate column for each unique value of an existing column?是否有一个 pandas 函数来转置数据框以为现有列的每个唯一值创建一个单独的列?
【发布时间】:2019-10-19 10:19:38
【问题描述】:

我想将我的数据框更改为可用于简单分析的格式。目前,我的数据框格式如下:

 Carrier | Service | Weight | Area | Charge
   A     |   GRND  |  1     |  2   | $5.0
   A     |   GRND  |  2     |  2   | $6.0
   A     |   GRND  |  3     |  2   | $7.0
   B     |   GRND  |  1     |  2   | $5.5
   B     |   GRND  |  3     |  2   | $6.9

我想将我的数据转换成以下格式:

  Service | Weight | Area | CarrierA_Charge | CarrierB_Charge
   GRND   |  1     |  2   |      $5.0       |   $5.5
   GRND   |  2     |  2   |      $6.0       |   NA
   GRND   |  3     |  2   |      $7.0       |   $6.9

最终,我的目标是创建一个列,为承运人提供服务、称重、区域的每个独特组合的最低费用,如下所示:

  Service | Weight | Area | CarrierA_Charge | CarrierB_Charge | min_charge |min_charge_carrier
   GRND   |  1     |  2   |      $5.0       |   $5.5          |  $5.0      |   A
   GRND   |  2     |  2   |      $6.0       |   NA            |  $6.0      |   A
   GRND   |  3     |  2   |      $7.0       |   $6.9          |  $6.9      |   B

是否有一个内置的 pandas 函数可以用来实现这一点,或者我如何在 python 中编写一个函数来实现这一点?

【问题讨论】:

  • 您应该可以使用pivot_table 方法来执行此操作。文档页面上提供了大量示例

标签: python pandas pivot transpose pivottable.js


【解决方案1】:

IIUC:

d = df.set_index(['Service', 'Weight', 'Area', 'Carrier']).Charge.unstack()
d.rename(columns=f'{d.columns.name}{{}}_Charge'.format) \
 .reset_index().rename_axis(None, axis=1)

  Service  Weight  Area  CarrierA_Charge  CarrierB_Charge
0    GRND       1     2              5.0              5.5
1    GRND       2     2              6.0              NaN
2    GRND       3     2              7.0              6.9

格式和附加列略有不同

d0 = df.set_index(['Service', 'Weight', 'Area', 'Carrier']).Charge.unstack()
d1 = pd.concat(dict(min_charge=d0.min(1), min_charge_carrier=d0.idxmin(1)), axis=1)
fmt = f'{d.columns.name}{{}}_Charge'.format

d0.rename(columns=fmt).join(d1).reset_index().rename_axis(None, axis=1)

  Service  Weight  Area  NoneA_Charge  NoneB_Charge  min_charge min_charge_carrier
0    GRND       1     2           5.0           5.5         5.0                  A
1    GRND       2     2           6.0           NaN         6.0                  A
2    GRND       3     2           7.0           6.9         6.9                  B

【讨论】:

  • 谢谢!这正是我想要的。
【解决方案2】:

数据透视表方法

# pivot table
pivot = df.pivot_table(columns = 'Carrier', index=['Service', 'Weight', 'Area'], values='Charge',
                       aggfunc = np.min).reset_index()

# rename columns here

【讨论】:

    【解决方案3】:

    要完整回答您的问题,包括额外的列:

    首先,我们创建您的数据透视表并相应地重命名您的列:

    第 1 步:旋转和重命名

    pivot = df.pivot_table(index=['Service', 'Weight', 'Area'], 
                           columns='Carrier', 
                           values='Charge', 
                           aggfunc=lambda x: ' '.join(x))
    
    pivot.columns = [pivot.columns.name + col + '_Charge' for col in pivot.columns]
    pivot.reset_index(inplace=True)
    
      Service  Weight  Area CarrierA_Charge CarrierB_Charge
    0    GRND       1     2            $5.0            $5.5
    1    GRND       2     2            $6.0             NaN
    2    GRND       3     2            $7.0            $6.9
    

    第 2 步创建额外的列:

    cols = ['CarrierA_Charge', 'CarrierB_Charge']
    
    for col in cols:
        pivot[col] = pivot[col].str.replace('$', '').astype(float)
    
    pivot['min_charge'] = pivot[['CarrierA_Charge', 'CarrierB_Charge']].min(axis=1)
    
    pivot['min_charge_carrier'] = np.where(pivot['min_charge'].eq(pivot['CarrierA_Charge']), 
                                           'A', 'B')
    

      Service  Weight  Area  CarrierA_Charge  CarrierB_Charge  min_charge min_charge_carrier
    0    GRND       1     2              5.0              5.5         5.0                  A
    1    GRND       2     2              6.0              NaN         6.0                  A
    2    GRND       3     2              7.0              6.9         6.9                  B
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-17
      • 2021-06-15
      • 1970-01-01
      • 1970-01-01
      • 2019-04-13
      • 2020-09-08
      • 2021-08-21
      • 2018-07-26
      相关资源
      最近更新 更多