Конвертировать столбцы в несколько строк в панде - PullRequest
0 голосов
/ 30 апреля 2018

У меня есть датафрейм, который выглядит примерно так:

   Deal  Year  Quarter_1  Quarter_2  Quarter_3  Financial_Data
h     1  1991          1          2          3             120
i     2  1992          4          5          6              80
j     3  1993          7          8          9             100

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

   Deal  Year  Quarter  Financial_Data
h     1  1991        1             120
i     1  1991        2             120
j     1  1991        3             120
k     2  1992        4              80
l     2  1992        5              80
m     2  1992        6              80
n     3  1993        7             100
o     3  1993        8             100
p     3  1993        9             100

Ответы [ 3 ]

0 голосов
/ 30 апреля 2018

Вы можете использовать melt метод.

df = pd.melt(d, id_vars=["Deal", "Year", "Financial_Data"], 
             value_name="Quarter").drop(['variable'],axis=1).sort_values('Quarter')

Выход

   Deal  Year  Financial_Data  Quarter
0     1  1991             120        1
3     1  1991             120        2
6     1  1991             120        3
1     2  1992              80        4
4     2  1992              80        5
7     2  1992              80        6
2     3  1993             100        7
5     3  1993             100        8
8     3  1993             100        9

Если у вас много столбцов, вы можете использовать метод df.columns.tolist(), чтобы удовлетворить ваши требования.

id_vars_list = df.columns.tolist()
id_vars_list = id_vars_list[:2] + id_vars_list[-1]

Заявление станет

df = pd.melt(d, id_vars=id_vars_list, 
             value_name="Quarter").drop(['variable'],axis=1).sort_values('Quarter')
0 голосов
/ 30 апреля 2018

Это делается с помощью melt:

pd.melt(df, id_vars=['Deal','Year','Financial_Data'], value_vars=['Quarter_1','Quarter_2','Quarter_3'])
   Deal  Year  Financial_Data   variable  value
0     1  1991             120  Quarter_1      1
1     2  1992              80  Quarter_1      4
2     3  1993             100  Quarter_1      7
3     1  1991             120  Quarter_2      2
4     2  1992              80  Quarter_2      5
5     3  1993             100  Quarter_2      8
6     1  1991             120  Quarter_3      3
7     2  1992              80  Quarter_3      6
8     3  1993             100  Quarter_3      9

Немного помыть:

>>> pd.melt(df, id_vars=['Deal','Year','Financial_Data'], value_vars=['Quarter_1','Quarter_2','Quarter_3']).drop('variable',axis=1).sort_values('value')
   Deal  Year  Financial_Data  value
0     1  1991             120      1
3     1  1991             120      2
6     1  1991             120      3
1     2  1992              80      4
4     2  1992              80      5
7     2  1992              80      6
2     3  1993             100      7
5     3  1993             100      8
8     3  1993             100      9
0 голосов
/ 30 апреля 2018

Один из способов - объединить ваши данные Quarter_X в список. Затем разверните список серий с помощью numpy / itertools в новом фрейме данных.

Это обычно более эффективно, чем методы stack или groupby. Обратите внимание, что результирующий индекс извлекается из родительской строки. Вам нужно будет переиндексировать по мере необходимости.

from itertools import chain
import numpy as np

df['Quarters'] = list(zip(df.Quarter_1, df.Quarter_2, df.Quarter_3))

lens = list(map(len, df.Quarters))

res = pd.DataFrame({'Deal': np.repeat(df.Deal, lens),
                    'Year': np.repeat(df.Year, lens),
                    'Quarter': list(chain.from_iterable(df.Quarters)),
                    'FinancialData': np.repeat(df.FinancialData, lens)})

print(res)

   Deal  FinancialData  Quarter  Year
h     1            120        1  1991
h     1            120        2  1991
h     1            120        3  1991
i     2             80        4  1992
i     2             80        5  1992
i     2             80        6  1992
j     3            100        7  1993
j     3            100        8  1993
j     3            100        9  1993

Для нескольких столбцов вышеуказанный метод может быть дорогим, но вы можете сделать:

res = pd.DataFrame({**{'Quarter': list(chain.from_iterable(df.Quarters))},
                    **{k: np.repeat(df[k], lens) for k in df if 'Quarter' not in k}})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...