Сводные таблицы на питоне - PullRequest
       46

Сводные таблицы на питоне

4 голосов
/ 27 сентября 2019

У меня есть CSV с таблицей данных.Я хотел бы прочитать CSV и написать новый файл XLSX на основе исходного CSV.

Однако я также хотел бы добавить новый столбец, который будет иметь значение, основанное на имени заголовка (например, если заголовок содержит слово online), и создать сортировку сводной таблицы на основе этой логики.,Таким образом, в отличие от трех столбцов для отведений, один столбец будет представлен тремя строками (для каждого столбца)

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.Но не могу понять, как вернуть столбцы в виде выигранных и потенциальных клиентов и извлечь только часть онлайн / розничная торговля / исходящая из существующих столбцов.

Ответы [ 4 ]

2 голосов
/ 27 сентября 2019

Вы можете использовать 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
2 голосов
/ 27 сентября 2019

С переименованием столбца вы можете использовать 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
2 голосов
/ 27 сентября 2019

Другой способ использования melt и series.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
1 голос
/ 27 сентября 2019

Используйте DataFrame.set_index с str.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
...