Существует ли функция pandas для транспонирования фрейма данных для создания отдельного столбца для каждого уникального значения существующего столбца? - PullRequest
1 голос
/ 04 июня 2019

Я хочу изменить свой фрейм данных на формат, который я могу использовать для простого анализа. В настоящее время мой фрейм данных имеет следующий формат:

 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 для достижения этой цели?

Ответы [ 3 ]

2 голосов
/ 04 июня 2019

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
1 голос
/ 04 июня 2019

Чтобы полностью ответить на ваш вопрос, включая дополнительные столбцы:

Сначала мы создадим ваш свод и соответственно переименуем столбцы:

Шаг 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
1 голос
/ 04 июня 2019

Подход сводной таблицы

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

# rename columns here
...