Как сгруппировать столбец и вывести несколько столбцов, разделенных вкладкой - Python - PullRequest
0 голосов
/ 22 февраля 2019

Моя цель - сгруппировать по столбцу «Пациент» и вывести каждого пациента в одну строку =, за которой следуют несколько столбцов из моего входного файла в последовательности.В идеале я бы предпочел иметь счетчик в заголовках столбцов.Вот мой пример входного файла:

Patient	Test	panel	gene	alteration
1	A	54	APC	E1345*
1	B	54	TP53	Y205H
1	C	54	APC	V2278V
2	A	54	KRAS	G12D
2	B	54	PTEN	L25L
3	A	54	KRAS	G13D
3	C	54	TP53	C141W
3	C	54	APC	R876* 
3	A	54	ERBB2	L663P
 

Ожидаемый вывод, где он группируется по столбцу «Пациент», а затем перебирает столбцы «Тест», «Ген» и «Изменение» для создания следующего:

Patient	Test	gene	alteration	Test	gene	alteration	Test	gene	alteration	Test	gene	alteration	Test	gene	alteration
1	A	APC	E1345*	B	TP53	Y205H	C	TP53	Y205H						
2	A	KRAS	G12D	B	PTEN	L25L									
3	A	KRAS	G13D	C	TP53	C141W	C	APC	R876* 	A	ERBB2	L663P	A	ERBB2	L663P

В идеале было бы неплохо # Тесты / ген / изменение, т. Е. Test_1 gene_1 alstruction_1 и т. Д. Однако я понимаю, что все усложняло.

вот что я пытался, и я не могу получить интересующий вывод

df = pd.read_table(args.md, sep="\t")
df=pd.DataFrame(df)  #I used an input file  
values=grouped['gene'].apply('\t'.join).reset_index()

вывод для этой функции 1) не позволил мне объединить больше, чем столбец 'gene', поэтому, если я использую ['gene', 'Test'] это не даст желаемого результата и 2) объединение '\ t' будет буквально выводиться как '\ t' вместо вкладки

Итак, я попробовал

grouped=df.groupby('Patient')
print grouped
values=grouped['gene'].apply('\t'.join).reset_index()
print values
id_df = grouped['Test'].apply(lambda x: pd.Series(x.values)).unstack()
id_df = id_df.rename(columns={i: 'Test{}'.format(i + 1) for i in range(id_df.shape[1])})
result = pd.concat([id_df, values], axis=1)
print(result)

Структура этой второй попытки не соответствовала тому, что мне было нужно, но она предоставила мне счетчик

Мне было интересно, может ли кто-нибудь дать какое-то понимание, чтобы получить желаемый результат.Я использовал приведенные выше команды при поиске SO, но не смог устранить неполадки.

Ответы [ 2 ]

0 голосов
/ 23 февраля 2019

Подход с использованием melt, groupby и unstack:

Данные

Оригинал

In []: df
Out[]:
   Patient Test  panel   gene alteration
0        1    A     54    APC     E1345*
1        1    B     54   TP53      Y205H
2        1    C     54    APC     V2278V
3        2    A     54   KRAS       G12D
4        2    B     54   PTEN       L25L
5        3    A     54   KRAS       G13D
6        3    C     54   TP53      C141W
7        3    C     54    APC     R876*
8        3    A     54  ERBB2      L663P

Tidy data

pd.DataFrame.melt позволяет привести в порядок эту таблицу:

In []: tidy = df.melt(id_vars=['Patient', 'Test'], value_vars=['panel', 'gene', 'alteration'])

In []: tidy
Out[]:
    Patient Test    variable   value
0         1    A       panel      54
1         1    B       panel      54
2         1    C       panel      54
3         2    A       panel      54
4         2    B       panel      54
5         3    A       panel      54
6         3    C       panel      54
7         3    C       panel      54
8         3    A       panel      54
9         1    A        gene     APC
10        1    B        gene    TP53
11        1    C        gene     APC
12        2    A        gene    KRAS
13        2    B        gene    PTEN
14        3    A        gene    KRAS
15        3    C        gene    TP53
16        3    C        gene     APC
17        3    A        gene   ERBB2
18        1    A  alteration  E1345*
19        1    B  alteration   Y205H
20        1    C  alteration  V2278V
21        2    A  alteration    G12D
22        2    B  alteration    L25L
23        3    A  alteration    G13D
24        3    C  alteration   C141W
25        3    C  alteration  R876*
26        3    A  alteration   L663P

Изменить форму

Использование goupby и unstack

In []: (tidy.groupby(['Patient', 'Test', 'variable'])  # group by three levels of interest
     ...:   .first()                                   # access values as a dataframe
     ...:   .unstack(level=[1,2]))                     # pivot on levels [1, 2] of multiindex
Out[]:
              value
Test              A                      B                      C
variable alteration  gene panel alteration  gene panel alteration  gene panel
Patient
1            E1345*   APC    54      Y205H  TP53    54     V2278V   APC    54
2              G12D  KRAS    54       L25L  PTEN    54        NaN   NaN   NaN
3              G13D  KRAS    54        NaN   NaN   NaN      C141W  TP53    54

Использование кросс-таблицы

Это дает эквивалентный результат:

In []: pd.crosstab(tidy.Patient,                # index
                   [tidy.Test, tidy.variable],  # columns
                   values=tidy.value,
                   aggfunc='first')             # get first value
Out[]:
Test              A                      B                      C
variable alteration  gene panel alteration  gene panel alteration  gene panel
Patient
1            E1345*   APC    54      Y205H  TP53    54     V2278V   APC    54
2              G12D  KRAS    54       L25L  PTEN    54        NaN   NaN   NaN
3              G13D  KRAS    54        NaN   NaN   NaN      C141W  TP53    54
0 голосов
/ 22 февраля 2019

Ниже одно из возможных решений.Может быть, не супер элегантный, но работает.

grouped = df.groupby('Patient')

col = ['Patient']
data = []
for p, g in grouped:
    d = {'Patient': p}
    g.reset_index(inplace=True)
    for i, row in g.iterrows():
        for c in range(2, len(g.columns)):
            col_name = g.columns[c] + '_' + str(i + 1)
            d[col_name] = row[g.columns[c]]
            if col_name not in col:
                col.append(col_name)
    data.append(d)

df = pd.DataFrame(data, columns=col)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...