2014-11-21 2 views
3

у меня есть TimeSeries dataframe, который похож на:поворотная панда dataframe в приставочные перевалы, а не мультииндексный

ts = pd.DataFrame([['Jan 2000','WidgetCo',0.5, 2], ['Jan 2000','GadgetCo',0.3, 3], ['Jan 2000','SnazzyCo',0.2, 4], 
      ['Feb 2000','WidgetCo',0.4, 2], ['Feb 2000','GadgetCo',0.5, 2.5], ['Feb 2000','SnazzyCo',0.1, 4], 
      ], columns=['month','company','share','price']) 

который выглядит как:

month company share price 
0 Jan 2000 WidgetCo 0.5 2.0 
1 Jan 2000 GadgetCo 0.3 3.0 
2 Jan 2000 SnazzyCo 0.2 4.0 
3 Feb 2000 WidgetCo 0.4 2.0 
4 Feb 2000 GadgetCo 0.5 2.5 
5 Feb 2000 SnazzyCo 0.1 4.0 

Я проворачивание этой таблицы следующим образом:

pd.pivot_table(ts,index='month', columns='company') 

Который получает меня:

  share      price     
company GadgetCo SnazzyCo WidgetCo GadgetCo SnazzyCo WidgetCo 
month               
Feb 2000  0.5  0.1  0.4  2.5  4  2 
Jan 2000  0.3  0.2  0.5  3.0  4  2 

Это то, что я хочу, за исключением того, что мне нужно свернуть MultiIndex так, что company используется в качестве префикса для share и price так:

  WidgetCo_share WidgetCo_price GadgetCo_share GadgetCo_price ... 
month                  
Jan 2000    0.5    2    0.3    3.0 
Feb 2000    0.4    2    0.5    2.5 

Я придумал эту функцию, чтобы сделать это но мне кажется, как плохое решение:

def pivot_table_to_flat(df, column, index): 
    res = df.set_index(index) 
    cols = res.drop(column, axis=1).columns.values 
    resulting_cols = [] 
    for prefix in res[column].unique(): 
     for col in cols: 
      new_col_name = prefix + '_' + col 
      res[new_col_name] = res[res[column] == prefix][col] 
      resulting_cols.append(new_col_name) 

    return res[resulting_cols] 

pivot_table_to_flat(ts, index='month', column='company') 

Что такое лучший способ достижения ось поворота, что приводит к колонкам с префиксами, в отличие от MultiIndex?

ответ

1

Я понял. Используя данные о MultiIndex делает довольно чистым раствором:

def flatten_multi_index(df): 
    mi = df.columns 
    suffixes, prefixes = mi.levels 
    col_names = [prefixes[i_p] + '_' + suffixes[i_s] for (i_s, i_p) in zip(*mi.labels)] 
    df.columns = col_names 
    return df 

flatten_multi_index(pd.pivot_table(ts,index='month', columns='company')) 

выше версия обрабатывает только 2D-MultiIndex, но она может быть обобщена в случае необходимости.

1

Обновление (на начало 2017 года и панда 0.19.2). Вы можете использовать .values на MultiIndex. Таким образом, этот фрагмент должен сгладить MultiIndex s для тех, кто в этом нуждается. Фрагмент является слишком умным, но не достаточно умным: он может обрабатывать имена индексов строк или столбцов из DataFrame, но он взорвется, если результат getattr(df,way) не вложен (т. Е. MultiIndex).

def flatten_multi(df, way='index'): # or way='columns' 
    assert way in {'index', 'columns'}, "I'm sorry Dave." 
    mi = getattr(df, way) 
    flat_names = ["_".join(s) for s in mi.values] 
    setattr(df, way, flat_names) 
    return df 
1

Это, кажется, еще проще:

df.columns = [' '.join(col).strip() for col in df.columns.values] 

Он принимает df с колонки мультииндексных и разглаживает заголовки столбцов, с ФР остающегося на месте.

(ref: @ andy-haden Python Pandas - How to flatten a hierarchical index in columns)

Смежные вопросы