2017-11-08 3 views
0

Ich versuche, ein Python-Skript zu schreiben, um Zählungen aus dem folgenden Datenrahmen zu generieren. Ich benutzte Count in Excel, aber Duplikate in 'Sample' und 'Region' verursachen Probleme mit Countifs.Pandas zählen einzigartig wenn Bedingung wahr

Beispiel Eingang df:

Sample Chr Start End Region Size Strand Chr2 Start2 End2 Coverage Overlap 
101 chr1 198661465 198661475 NM_002838_PTPRC_intron_2_R 10 + chr1 198608563 198661471 0 6 
101 chr1 198661465 198661475 NM_001267798_PTPRC_intron_2_R 10 + chr1 198608563 198661471 0 6 
101 chr1 198661465 198661475 NM_080921_PTPRC_intron_2_R 10 + chr1 198608563 198661471 0 6 
101 chr1 236966727 236966942 NM_000254_MTR_cds_2 215 + chr1 236966742 236966743 11 1 
101 chr1 236966727 236966942 NM_001291939_MTR_cds_2 215 + chr1 236966742 236966743 11 1 
101 chr1 236966742 236966942 NM_001291940_MTR_5utr_2 200 + chr1 236966742 236966743 11 1 
101 chr1 236979843 236979853 NM_000254_MTR_intron_8_L 10 + chr1 236979846 236979847 9 1 
101 chr1 236979843 236979853 NM_000254_MTR_intron_8_L 10 + chr1 236979847 236979848 8 1 
101 chr1 236979843 236979853 NM_000254_MTR_intron_8_L 10 + chr1 236979848 236979852 7 4 
101 chr1 236979843 236979853 NM_000254_MTR_intron_8_L 10 + chr1 236979852 236979854 6 1 
101 chr1 236979843 236979853 NM_001291940_MTR_intron_8_L 10 + chr1 236979846 236979847 9 1 
101 chr1 236979843 236979853 NM_001291940_MTR_intron_8_L 10 + chr1 236979847 236979848 8 1 
101 chr1 236979843 236979853 NM_001291940_MTR_intron_8_L 10 + chr1 236979848 236979852 7 4 

So kann eine einzelne Probe, die die gleiche ‚Region‘ mehr aufgelistet als einmal (verschiedene Koordinaten, aber das zum Zählen spielt keine Rolle).

gewünschte Ausgabe 1 - zählt von 'Sample', wenn 'Region' enthält "UTR" oder "Introns" oder "CDs", auf der doppelten 'Region' pro 'Sample':

Sample Total Intron UTR CDS 
101 68 40 13 15 
102 64 38 13 13 

Ausgang 2 gewünschte - Summe von 'Overlap' durch 'Probe', wenn 'Region' enthält "UTR" oder "Intron" oder "CDs":

Sample Total Intron UTR CDS 
101 2838 321 1433 1084 
102 2524 291 1449 784 

gewünschten Ausgang 3 - Liste des ‚Regio n‘mit Zählungen für die Anzahl der Proben, die mit dieser‚Region‘aufgeführt

Region Num Samples 
ENST00000390559_IGHM_cds_4 2 
ENST00000390559_IGMH_cds_1 2 
ENST00000390559_IGMH_cds_2 2 
ENST00000390559_IGMH_cds_3 12 
ENST00000390559_IGMH_intron_1_L 2 
ENST00000390559_IGMH_intron_1_R 2 
ENST00000390559_IGMH_intron_2_L 10 

EDIT: Ich habe herausgefunden, wie Ausgang zu bekommen # 3:

df.groupby('Region').Sample.nunique() 

und ich kann für die Ausgabe Gesamt erhalten # 1 mit:

df.groupby('Sample').Region.nunique() 

jetzt muss ich nur noch herausfinden, wie meine Gruppen zu filtern, für die Aufnahme ‚UTR/cds/Intron‘ und Addition der ‚Overlap‘ gefilterter Gruppen.

Antwort

0

Wenn jemand auf ein ähnliches Problem stößt, ist hier, was ich zur Generierung der drei beschriebenen Ausgänge kam. Es ist vielleicht nicht die eleganteste Lösung, aber es funktioniert!

import pandas as pd 
import argparse 
import os 
import sys 

#arguments 
parser = argparse.ArgumentParser(description="Generate counts by sample and total bases by sample of low coverage regions") 

parser.add_argument("-i", "--input", help="input filename", required=True) 
parser.add_argument("-o", "--output", help="output basename", required=True) 

args = parser.parse_args() 

#output filenames 
region_count_file = args.output + "_region_count.txt" 
bases_count_file = args.output + "_bases_count.txt" 
sample_count_file = args.output + "_sample_count.txt" 

#read in 
df = pd.read_table(args.input) 

#check output doesn't exist 
if os.path.exists(region_count_file) or os.path.exists(bases_count_file) or os.path.exists(sample_count_file): 
    sys.exit("ERROR: output basename %s files already exist" % args.output) 

#for filtering on different regions 
intron = df['Region'].str.contains('intron') 
utr = df['Region'].str.contains('utr') 
cds = df['Region'].str.contains('cds') 

#count regions per sample 
unique_regions = df.groupby('Sample').Region.nunique() 
unique_intron = df[intron].groupby('Sample').Region.nunique() 
unique_utr = df[utr].groupby('Sample').Region.nunique() 
unique_cds = df[cds].groupby('Sample').Region.nunique() 

#sum bases per sample 
bases_total = df.groupby(['Sample'])['Overlap'].sum() 
bases_intron = df[intron].groupby(['Sample'])['Overlap'].sum() 
bases_utr = df[utr].groupby(['Sample'])['Overlap'].sum() 
bases_cds = df[cds].groupby(['Sample'])['Overlap'].sum() 

#count samples per region 
samples_per_region = df.groupby('Region').Sample.nunique() 

#format regions per sample for output 
combine_region_count = pd.concat([unique_regions,unique_intron,unique_utr,unique_cds], axis=1) 
combine_region_count.columns = 'Total','Intron','UTR','CDS' 

#format bases per sample for output 
combine_bases = pd.concat([bases_total,bases_intron,bases_utr,bases_cds], axis=1) 
combine_bases.columns = 'Total','Intron','UTR','CDS' 

#format samples per region for output 
#samples_per_region.reset_index(name='Num Samples') 
#not sure why this is not working, but not that important 


#output each 
combine_region_count.to_csv(region_count_file,sep='\t') 
combine_bases.to_csv(bases_count_file,sep='\t') 
samples_per_region.to_csv(sample_count_file,sep='\t') 
Verwandte Themen