Размещать кластерные тепловые карты с огромным файлом на питоне? - PullRequest
0 голосов
/ 07 ноября 2018

У меня есть три файла, каждый размером около 3 ГБ, которые содержат информацию о картировании генома, например:

#RefName    Pos Coverage
BGC0000001_59320bp  0   0
BGC0000001_59320bp  1   0
BGC0000001_59320bp  2   0
BGC0000001_59320bp  3   0
BGC0000001_59320bp  4   0
BGC0000001_59320bp  5   0
BGC0000001_59320bp  6   0
BGC0000001_59320bp  7   0
BGC0000001_59320bp  8   0
BGC0000001_59320bp  9   0
BGC0000001_59320bp  10  0
BGC0000001_59320bp  11  0
BGC0000001_59320bp  12  0
BGC0000001_59320bp  13  0
BGC0000001_59320bp  14  0
BGC0000001_59320bp  15  0
BGC0000001_59320bp  16  0
BGC0000001_59320bp  17  0
BGC0000001_59320bp  18  0
BGC0000001_59320bp  19  0
BGC0000001_59320bp  20  0
BGC0000001_59320bp  21  0
BGC0000001_59320bp  22  0
BGC0000001_59320bp  23  0
BGC0000001_59320bp  24  0
BGC0000001_59320bp  25  0
BGC0000001_59320bp  26  0
BGC0000001_59320bp  27  0
BGC0000001_59320bp  28  0
BGC0000001_59320bp  29  0
BGC0000001_59320bp  30  0
BGC0000001_59320bp  31  0
BGC0000001_59320bp  32  0
BGC0000001_59320bp  33  0
BGC0000001_59320bp  34  0
BGC0000001_59320bp  35  0

.
.
.
.

Первый столбец = имя гена; 2-й столбец = положение или локусы каждого основания гена; 3-й столбец = охват каждой базы или позиции.

Например: первый ген 'BGC0000001_59320bp' имеет длину 59320 б.п., поэтому для этого гена будет 59320 строк, а затем появится следующий ген.

Я хотел бы создать кластерную тепловую карту следующим образом: enter image description here

Ось Y - это каждый ген, такой как BGC0000001, BGC0000002, .... Ось х - это положение гена в виде бина. Поскольку каждый ген имеет разную длину, я буду складывать их в одинаковое количество бинов, скажем, в 100 бинов. Это делает ось х стать bin1, bin2, bin3, ..., bin100. Например, BGC0000001 = 59320 п.н., BGC0000002 = 10000 б.п., я сгруппирую каждый ген в 100 бинов, поэтому для BGC0000001, bin1 = 593 б.п., bin2 = 593 б.п., ... bin100 = 595 б.п.; для BGC0000002: bin1 = 100 б.п., bin2 = 100 б.п. ... bin100 = 100 б.п. Я помещу сумму покрытия в каждую ячейку как значения для построения графика. Например: для BGC0000001: bin1 = сумма (покрытие первых 593 б.п.), bin2 = сумма (покрытие 2-х 593 б.п.) ...

Наконец, я буду использовать объединенные данные для построения кластеризованной тепловой карты. У меня есть три образца файлов, чтобы сделать три участка. Поскольку данные огромны, я пробую приведенный ниже код, который на самом деле не чист, и это занимает вечность:

import pandas as pd
import matplotlib.pyplot as plt
import sys
import os
from scipy.stats import binned_statistic

import seaborn as sns



def getFiles(filePath):
    coverageFile = []    

    for file in os.listdir(filePath):
        if file.endswith(".coverage"):
            coverageFile.append(file)
        else:
            pass          

    print(coverageFile)

    return coverageFile



def binCov(df,name,nBins):
    genomeMap = df[df.node == name].coverage
    bin_sums, bin_edges, binnumber = binned_statistic (range(len(genomeMap)), genomeMap, 
                                                        statistic = 'sum', bins = nBins)
    bin_width = (bin_edges[1] - bin_edges[0])
    bin_centers = bin_edges[1:] - bin_width*0.5

    df1 = pd.DataFrame({'covSum':bin_sums})

    df1.insert(1,'gene',name)
    df1.insert(2,'loci',range(1, len(df1)+1))
    df1.insert(2,'covNorm',df1.covSum)
    df1.loc[df1.covSum >5000, 'covNorm'] = 5000
    df1.drop('covSum', axis =1, inplace = True)

    return df1


files = getFiles(os.getcwd())

df_nac = pd.read_csv(files[0], sep = '\t')
df_nac.columns = ['node', 'loci', 'coverage']


df_ks = pd.read_csv(files[1], sep = '\t')
df_ks.columns = ['node', 'loci', 'coverage']

df_meta = pd.read_csv(files[2], sep = '\t')
df_meta.columns = ['node', 'loci', 'coverage']

cluster_names = df_nac.node.tolist()

cluster_nac = {}
cluster_ks = {}
cluster_meta = {}


for name in cluster_names:
    cluster_nac[name] = binCov(df_nac, name, 100)
    cluster_ks[name] = binCov(df_ks, name, 100)
    cluster_meta[name] = binCov(df_meta, name, 100)

cluster_nac_all = pd.concat(cluster_nac.values(), ignore_index=True)
cluster_ks_all = pd.concat(cluster_ks.values(), ignore_index=True)
cluster_meta_all = pd.concat(cluster_meta.values(), ignore_index=True)


nac_p = cluster_nac_all.pivot("gene", "loci", "covNorm")
ks_p = cluster_ks_all.pivot("gene", "loci", "covNorm")
meta_p = cluster_meta_all.pivot("gene", "loci", "covNorm")



sns.set_style("darkgrid")

plt.figure(figsize = (5,10))
# cmap="Greens", , linecolor='yellow', alpha = 0.9,cmap="YlGnBu"
g1 = sns.heatmap(meta_p, xticklabels=True, yticklabels=True, cmap="BuPu", cbar = False)

g1.set_xlabel('Bases (binned)')
g1.set_ylabel('')

g1.set_xticks([])
g1.set_yticks([])

plt.savefig('meta_sumCov.png',dpi = 300, bbox_inches = 'tight')

plt.figure(figsize = (5,10))
# cmap="Greens", , linecolor='yellow', alpha = 0.9,cmap="YlGnBu"
g2 = sns.heatmap(nac_p, xticklabels=True, yticklabels=True, cmap="BuPu", cbar = False)

g2.set_xlabel('Bases (binned)')
g2.set_ylabel('')

g2.set_xticks([])
g2.set_yticks([])

plt.savefig('nac_sumCov.png',dpi = 300, bbox_inches = 'tight')

plt.figure(figsize = (5,10))
# cmap="Greens", , linecolor='yellow', alpha = 0.9,cmap="YlGnBu"
g3 = sns.heatmap(ks_p, xticklabels=True, yticklabels=True, cmap="BuPu", 
    cbar_kws = dict(use_gridspec=False,location="right"))

g3.set_xlabel('Bases (binned)')
g3.set_ylabel('')

g3.set_xticks([])
g3.set_yticks([])

plt.savefig('ks_sumCov.png',dpi = 300, bbox_inches = 'tight')

Я позволил ему работать в течение 10 часов и продолжал работать, хотя это не показывало никакой ошибки. Я не думаю, что Pandas хорош для больших файлов, но я не знаком с другими более быстрыми инструментами. Пожалуйста, помогите мне.

Спасибо.

...