pandas wide_long vs (stack and melt) для преобразования фрейма данных - PullRequest
1 голос
/ 06 ноября 2019

У меня есть фрейм данных, как показано ниже

df = pd.DataFrame({
'subject_ID':[1,2,3,4,5],
'date_visit':['1/1/2020','3/3/2200','13/11/2100','24/05/2198','30/03/2071'],
'a11fever':['Yes','No','Yes','Yes','No'],
'a12diagage':[36,34,42,40,np.nan],
'a12diagyr':[2021,3213,2091,4567,8901],
'a12diagyrago':[6,np.nan,9,np.nan,np.nan]})

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

enter image description here

Хотя я смог сделать это успешно, используя pd.melt и stack, я не смог сделать то же самое, используя wide_long.

pd.melt(df, id_vars =['subject_ID','date_visit'], value_vars =['a11fever', 'a12diagage', 'a12diagyr','a12diagyrago'])  # works fine

pd.wide_to_long(df, stubnames=['measurement', 'val'],i=(['subject_ID','date_visit']), j='grp').sort_index(level=0) # returns 0 records

df.set_index(['subject_ID','date_visit']).stack().reset_index() #works fine

другой вопрос, который у меня есть,

a) Всегда ли мы должны упоминать все имена столбцов, которые мы хотели бы преобразовать в value_vars разделе pd.melt. Мои реальные данные будут иметь более 120 столбцов. Должен ли я упомянуть все из них здесь?

Можете ли вы помочь мне с этим, как это сделать, используя wide_long?

Ответы [ 2 ]

4 голосов
/ 06 ноября 2019

Должны ли мы всегда упоминать все имена столбцов, которые мы хотели бы преобразовать в разделе value_vars pd.melt. Мои реальные данные будут иметь более 120 столбцов. Должен ли я упомянуть все из них здесь?

Нет, необязательно, если пропущен параметр value_vars, тогда используются все столбцы без id_vars:

df = pd.melt(df, id_vars =['subject_ID','date_visit'])
print (df)

    subject_ID  date_visit      variable value
0            1    1/1/2020      a11fever   Yes
1            2    3/3/2200      a11fever    No
2            3  13/11/2100      a11fever   Yes
3            4  24/05/2198      a11fever   Yes
4            5  30/03/2071      a11fever    No
5            1    1/1/2020    a12diagage    36
6            2    3/3/2200    a12diagage    34
7            3  13/11/2100    a12diagage    42
8            4  24/05/2198    a12diagage    40
9            5  30/03/2071    a12diagage   NaN
10           1    1/1/2020     a12diagyr  2021
11           2    3/3/2200     a12diagyr  3213
12           3  13/11/2100     a12diagyr  2091
13           4  24/05/2198     a12diagyr  4567
14           5  30/03/2071     a12diagyr  8901
15           1    1/1/2020  a12diagyrago     6
16           2    3/3/2200  a12diagyrago   NaN
17           3  13/11/2100  a12diagyrago     9
18           4  24/05/2198  a12diagyrago   NaN
19           5  30/03/2071  a12diagyrago   NaN
2 голосов
/ 06 ноября 2019

Это не вариант использования для pd.wide_to_long, поскольку он будет генерировать неправильный вывод. Вы должны использовать stubnames, и они будут преобразованы в столбцы (a11 & a12). Смотрите пример:

melt = pd.wide_to_long(df, 
                i=['subject_ID', 'date_visit'], 
                stubnames=['a11', 'a12'], 
                suffix='\D+', 
                j='fever_diag').reset_index()
    subject_ID  date_visit fever_diag  a11     a12
0            1    1/1/2020    diagage  NaN    36.0
1            1    1/1/2020     diagyr  NaN  2021.0
2            1    1/1/2020  diagyrago  NaN     6.0
3            1    1/1/2020      fever  Yes     NaN
4            2    3/3/2200    diagage  NaN    34.0
5            2    3/3/2200     diagyr  NaN  3213.0
6            2    3/3/2200  diagyrago  NaN     NaN
7            2    3/3/2200      fever   No     NaN
8            3  13/11/2100    diagage  NaN    42.0
9            3  13/11/2100     diagyr  NaN  2091.0
10           3  13/11/2100  diagyrago  NaN     9.0
11           3  13/11/2100      fever  Yes     NaN
12           4  24/05/2198    diagage  NaN    40.0
13           4  24/05/2198     diagyr  NaN  4567.0
14           4  24/05/2198  diagyrago  NaN     NaN
15           4  24/05/2198      fever  Yes     NaN
16           5  30/03/2071    diagage  NaN     NaN
17           5  30/03/2071     diagyr  NaN  8901.0
18           5  30/03/2071  diagyrago  NaN     NaN
19           5  30/03/2071      fever   No     NaN
...