5.Python

Python Tutorial

life_is_short

Install Anaconda Python

    Easy install of data science packages (binary distribution)
    Package management with conda
anaconda_packages
Install Python packages using conda:
1
conda install h5py
Copied!
Update a package to the latest version:
1
conda update h5py
Copied!
Install Python packages using pip:
1
pip install h5py
Copied!
Update a package using pip:
1
pip install --upgrade h5py
Copied!

Python language tips

Compatibility between Python 3.x and Python 2.x

Biggest difference: print is a function rather than statement in Python 3
This does not work in Python 3
1
print 1, 2, 3
Copied!
Solution: use the __future__ module
1
from __future__ import print_function
2
# this works both in Python 2 and Python 3
3
print(1, 2, 3)
Copied!
Second biggest difference: some package/function names in the standard library are changed
Python 2 => Python 3
1
cStringIO => io.StringIO
2
Queue => queue
3
cPickle => pickle
4
ConfigParser => configparser
5
HTMLParser => html.parser
6
SocketServer => socketserver
7
SimpleHTTPServer => http.server
Copied!
Solution: use the six module

Get away from IndentationError

Python forces usage of tabs/spaces to indent code
1
# use a tab
2
for i in range(3):
3
print(i)
4
# use 2 spaces
5
for i in range(3):
6
print(i)
7
# use 4 spaces
8
for i in range(3):
9
print(i)
Copied!
Best practice: always use 4 spaces. You can set whether to use spaces(soft tabs) or tabs for indentation.
In vim editor, use :set list to inspect incorrect number of spaces/tabs.

Add Shebang and encoding at the beginning of executable scripts

Create a file named welcome.py
1
#! /usr/bin/env python
2
# -*- coding: UTF-8 -*-
3
print('welcome to python!')
Copied!
Then set the python script as executable:
1
chmod +x welcome.py
Copied!
Now you can run the script without specifying the Python interpreter:
1
./welcome.py
Copied!

All variables, functions, classes are dynamic objects

1
class MyClass():
2
def __init__(self, name):
3
self.name = name
4
# assign an integer to a
5
a = 1
6
print(type(a))
7
# assign a string to a
8
a = 'abc'
9
print(type(a))
10
# assign a function to a
11
a = range
12
print(type(a))
13
print(a(10))
14
# assign a class to a
15
a = MyClass
16
print(type(a))
17
b = a('myclass')
18
print(b.name)
19
# assign an instance of a class to a
20
a = MyClass('myclass')
21
print(b.name)
22
# get type of a
23
print(type(a))
Copied!

All python variables are pointers/references

1
a = [1, 2, 3]
2
print('a = ', a)
3
# this add another refrence to the list
4
b = a
5
print('b = ', b)
6
# this will change contents of both a and b
7
b[2] = 4
8
print('a = ', a)
9
print('b = ', b)
Copied!

Use deepcopy if you really want to COPY a variable

1
from copy import deepcopy
2
a = {'A': [1], 'B': [2], 'C': [3]}
3
print(a)
4
# shallow copy
5
b = dict(a)
6
# modify elements of b will change contents of a
7
b['A'].append(2)
8
print('a = ', a)
9
print('b = ', b)
10
# this also does not work
11
c = {k:v for k, v in a}
12
c['A'].append(3)
13
print('a = ', a)
14
print('c = ', c)
15
# recurrently copy every object of a
16
d = deepcopy(a)
17
# modify elements of c will not change contents of a
18
d['A'].append(2)
19
print('a = ', a)
20
print('d = ', d)
Copied!

What if I accidentally overwrite my builtin functions?

You can refer to (https://docs.python.org/2/library/functions.html) for builtin functions in the standard library.
1
A = [1, 2, 3, 4]
2
# Ops! the builtin function sum is overwritten by a number
3
sum = sum(A)
4
# this will raise an error because sum is not a function now
5
print(sum(A))
6
# recover the builtin function into the current environment
7
from __builtin__ import sum
8
# this works because sum is a function
9
print(sum(A))
Copied!
Note: in Python 3, you should import from builtins rather than __builtin__
1
from builtins import sum
Copied!

int is of arbitrary precision in Python!

In Pyhton:
1
print(2**10000)
Copied!
In R:
1
print(2^10000)
Copied!

Easiest way to swap values of two variables

In C/C++:
1
int a = 1, b = 2, t;
2
t = a;
3
a = b;
4
b = t;
Copied!
In Python:
1
a = 1
2
b = 2
3
b, a = a, b
4
print(a, b)
Copied!

List comprehension

Use for-loops:
1
a = []
2
for i in range(10):
3
a.append(i + 10)
4
print(a)
Copied!
Use list comprehension
1
a = [i + 10 for i in range(10)]
2
print(a)
Copied!

Dict comprehension

Use for-loops:
1
a = {}
2
for i in range(10):
3
a[i] = chr(ord('A') + i)
4
print(a)
Copied!
Use dict comprehension:
1
a = {i:chr(ord('A') + i) for i in range(10)}
2
print(a)
Copied!

For the one-liners

Use ';' instead of '\n':
1
# print the first column of each line
2
python -c 'import sys; print("\n".join(line.split("\t")[0] for line in sys.stdin))'
Copied!
For more examples of one-liners, please refer to (https://wiki.python.org/moin/Powerful Python One-Liners).

Read from standard input

1
import sys
2
# read line by line
3
for line in sys.stdin:
4
print(line)
Copied!

Order of dict keys are NOT as you expected

1
a = {'A': 1, 'B': 2, 'C': 3, 'D': 4, 'E': 5, 'F': 6}
2
# not in lexicographical order
3
print([key for key in a])
4
# now in lexicographical order
5
print([key for key in sorted(a)])
Copied!

Use enumerate() to add a number during iteration

1
A = ['a', 'b', 'c', 'd']
2
for i, a in enumerate(A):
3
print(i, a)
Copied!

Reverse a list

1
# a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
2
a = range(10)
3
print(a)
4
print(a[::-1])
Copied!

Strings are immutable in Python

1
a = 'ABCDF'
2
# will raise an Error
3
a[4] = 'E'
4
# convert str to bytearray
5
b = bytearray(a)
6
# bytearray are mutable
7
b[4] = 'E'
8
# convert bytearray to str
9
print(str(b))
Copied!

tuples are hashable while lists are not hashable

1
# create dict using tuples as keys
2
d = {
3
('chr1', 1000, 2000): 'featureA',
4
('chr1', 2000, 3000): 'featureB',
5
('chr1', 3000, 4000): 'featureC',
6
('chr1', 4000, 5000): 'featureD',
7
('chr1', 5000, 6000): 'featureE',
8
('chr1', 6000, 7000): 'featureF'
9
}
10
# query the dict using tuples
11
print(d[('chr1', 3000, 4000)])
12
print(d[('chr1', 6000, 7000)])
13
# will raise an error
14
d = {['chr1', 1000, 2000]: 'featureA'}
Copied!

Use itertools

Nested loops in a more concise way:
1
A = [1, 2, 3]
2
B = ['a', 'b', 'c']
3
C = ['i', 'j', 'k']
4
D = ['x', 'y', 'z']
5
# Use nested for-loops
6
for a in A:
7
for b in B:
8
for c in C:
9
for d in D:
10
print(a, b, c, d)
11
# Use itertools.product
12
import itertools
13
for a, b, c, d in itertools.product(A, B, C, D):
14
print(a, b, c, d)
Copied!
Get all combinations of a list:
1
A = ['A', 'B', 'C', 'D']
2
# Use itertools.combinations
3
import itertools
4
for a, b, c in itertools.combinations(A, 3):
5
print(a, b, c)
Copied!

Convert iterables to lists

1
import itertools
2
A = [1, 2, 3]
3
B = ['a', 'b', 'c']
4
a = itertools.product(A, B)
5
# a is a iterable rather than a list
6
print(a)
7
# a is a list now
8
a = list(a)
9
print(a)
Copied!

Use the zip() function to transpose nested lists/tuples/iterables

1
records = [
2
('chr1', 1000, 2000),
3
('chr1', 2000, 3000),
4
('chr1', 3000, 4000),
5
('chr1', 4000, 5000),
6
('chr1', 5000, 6000),
7
('chr1', 6000, 7000)
8
]
9
# iterate by rows
10
for chrom, start, end in records:
11
print(chrom, start, end)
12
# extract columns
13
chroms, starts, ends = zip(*records)
14
# build records from columns
15
# now records2 is the same as records
16
records2 = zip(chroms, starts, ends)
17
print(records)
Copied!

Global and local variables

1
# a is global
2
a = 1
3
def print_local():
4
# a is local
5
a = 2
6
print(a)
7
8
def print_global():
9
# a is global
10
global a
11
a = 2
12
print(a)
13
14
# print global variable
15
print(a)
16
# print local variable from function
17
print_local()
18
# a is unchanged
19
print(a)
20
# change and print global from function
21
print_global()
22
# a is changed
23
print(a)
Copied!

Use defaultdict

Use dict:
1
d = {}
2
d['a'] = []
3
d['b'] = []
4
d['c'] = []
5
# extend list with new elements
6
d['a'] += [1, 2]
7
d['b'] += [3, 4, 5]
8
d['c'] += [6]
9
for key, val in d.items():
10
print(key, val)
Copied!
Use defaultdict:
1
from collections import defaultdict
2
# a new list is created automatically when new elements are added
3
d = defaultdict(list)
4
# extend list with new elements
5
d['a'] += [1, 2]
6
d['b'] += [3, 4, 5]
7
d['c'] += [6]
8
for key, val in d.items():
9
print(key, val)
Copied!

Use generators

Example: read a large FASTA file
1
def append_extra_line(f):
2
"""Yield an empty line after the last line in the file
3
"""
4
for line in f:
5
yield line
6
yield ''
7
8
def read_fasta(filename):
9
with open(filename, 'r') as f:
10
name = None
11
seq = ''
12
for line in append_extra_line(f):
13
if line.startswith('>') or (len(line) == 0):
14
if (len(seq) > 0) and (name is not None):
15
yield (name, seq)
16
if line.startswith('>'):
17
name = line.strip()[1:].split()[0]
18
seq = ''
19
else:
20
if name is None:
21
raise ValueError('the first line does not start with ">"')
22
seq += line.strip()
23
# print sequence name and length of each
24
for name, seq in read_fasta('test.fa'):
25
print(name, len(seq))
Copied!

Turn off annoying KeyboardInterrupt and BrokenPipe Error

Without exception handling (press Ctrl+C):
1
import time
2
time.sleep(300)
Copied!
With exception handling (press Ctrl+C):
1
import time
2
import errno
3
4
try:
5
time.sleep(300)
6
except KeyboardInterrupt:
7
sys.exit(1)
8
except OSError as e:
9
if e.errno == errno.EPIPE:
10
sys.exit(-e.errno)
Copied!

Class and instance variables

1
class MyClass():
2
name = 'class_name'
3
def __init__(self, name):
4
self.name = name
5
6
def change_name(self, name):
7
self.name = name
8
9
# print class variable
10
print(MyClass.name)
11
# create an instance from MyClass
12
a = MyClass('instance_name')
13
# print instance name
14
print(a.name)
15
# change instance name
16
a.change_name('instance_new_name')
17
print(a.name)
18
print(MyClass.name)
19
# change class name
20
MyClass.name = 'class_new_name'
21
print(a.name)
22
print(MyClass.name)
Copied!

Useful Python packages for data analysis

Browser-based interactive programming in Python: jupyter

Start jupyter notebook
1
jupyter notebook --no-browser
Copied!
Jupyter notebooks manager
jupyter_main
Jupyter process manager
jupyter_processes
Jupyter notebook
jupyter_notebook
Integrate with matplotlib
jupyter_matplotlib
Browser-based text editor
jupyter_text_editor
Browser-based terminal
jupyter_termimal
Display image
jupyter_image
Display dataframe
jupyter_dataframe
Display audio
jupyter_audio
Embedded markdown
jupyter_markdown

Python packages for scientific computing

scipy ecosystem

Vector arithmetics: numpy

Example:
1
import numpy as np
2
# create an empty matrix of shape (5, 4)
3
X = np.zeros((5, 4), dtype=np.int32)
4
# create an array of length 5: [0, 1, 2, 3, 4]
5
y = np.arange(5)
6
# create an array of length 4: [0, 1, 2, 3]
7
z = np.arange(4)
8
# set Row 1 to [0, 1, 2, 3]
9
X[0] = np.arange(4)
10
# set Row 2 to [1, 1, 1, 1]
11
X[1] = 1
12
# add 1 to all elements
13
X += 1
14
# add y to each row of X
15
X += y.reshape((-1, 1))
16
# add z to each column of X
17
X += z.reshape((1, -1))
18
# get row sums =>
19
row_sums = X.sum(axis=1)
20
# get column sums
21
col_sums = X.sum(axis=0)
22
# matrix multiplication
23
A = X.dot(X.T)
24
# save matrix to text file
25
np.savetxt('data.txt', A)
Copied!

Numerical analysis (probability distribution, signal processing, etc.): scipy

scipy.stats contains a large number probability distributions:
Unified interface for all probability distributions: ![scipy_stats_distribution]

Just-in-time (JIT) compiler for vector arithmetics

Compile python for-loops to native code to achive similar performance to C/C++ code. Example:
1
from numba import jit
2
from numpy import arange
3
4
# jit decorator tells Numba to compile this function.
5
# The argument types will be inferred by Numba when function is called.
6
@jit
7
def sum2d(arr):
8
M, N = arr.shape
9
result = 0.0
10
for i in range(M):
11
for j in range(N):
12
result += arr[i,j]
13
return result
14
15
a = arange(9).reshape(3,3)
16
print(sum2d(a))
Copied!

Library for symbolic computation: sympy

sympy

Operation on data frames: pandas

Example:
1
import pandas as pd
2
# read a bed file
3
genes = pd.read_table('gene.bed', header=None, sep='\t',
4
names=('chrom', 'start', 'end', 'gene_id', 'score', 'strand', 'biotype'))
5
# get all gene IDs
6
gene_ids = genes['gene_id']
7
# set gene_id as index
8
genes.index = genes['gene_id']
9
# get row with given gene_id
10
gene = genes.loc['ENSG00000212325.1']
11
# get rows with biotype = 'protein_coding'
12
genes_selected = genes[genes['biotype'] == 'protein_coding']]
13
# get protein coding genes in chr1
14
genes_selected = genes.query('(biotype == "protein_coding") and (chrom == "chr1")')
15
# count genes for each biotype
16
biotype_counts = genes.groupby('biotype')['gene_id'].count()
17
# add a column for gene length
18
genes['length'] = genes['end'] - genes['start']
19
# calculate average gene length for each chromosome and biotype
20
length_table = genes.pivot_table(values='length', index='biotype', columns='chrom')
21
# save DataFrame to Excel file
22
length_table.to_excel('length_table.xlsx')
Copied!

Basic graphics and plotting: matplotlib

matplotlib

Statistical data visualization: seaborn

seaborn

Interactive programming in Python: ipython

ipython

Statistical tests: statsmodels

statsmodels

Machine learning algorithms: scikit-learn

scikit-learn
Example:
1
from sklearn.datasets import make_classification
2
from sklearn.linear_model import LogisticRegression
3
from sklearn.model_selection import train_test_split
4
from sklearn.metrics import roc_auc_score, accuracy_score
5
6
# generate ramdom data
7
X, y = make_classification(n_samples=1000, n_classes=2, n_features=10)
8
# split dataset into training and test dataset
9
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
10
# create an classifier object
11
model = LogisticRegression()
12
# training the classifier
13
model.fit(X_train, y_train)
14
# predict outcomes on the test dataset
15
y_pred = model.predict(X_test)
16
# evalualte the classification performance
17
print('roc_auc_score = %f'%roc_auc_score(y_test, y_pred))
18
print('accuracy_score = %f'%accuracy_score(y_test, y_pred))
Copied!

Natural language analysis: gensim

HTTP library: requests

requests

Lightweight Web framework: flask

flask

Deep learning framework: tensorflow

High-level deep learning framework: keras

Operation on sequence and alignment formats: biopython

1
from Bio import SeqIO
2
for record in SeqIO.parse('test.fa', 'fasta'):
3
print(record.id, len(record.seq))
Copied!
1
from Bio import SeqIO
2
from Bio.Seq import Seq
3
from Bio.SeqRecord import SeqRecord
4
sequences = [
5
SeqRecord(Seq('ACCGGTATCTATATCCCCGAGAGGAATGGGTCAGACATGGACCTAC'), id='A', description=''),
6
SeqRecord(Seq('TTACAATGTGGCAGTGAACGCGTGACAATCCTCCCCGTTGGACAT'), id='B', description=''),
7
SeqRecord(Seq('CAAAGCTGCATCGAATTGTCGAGACAACACTAGATTTAAGCGCA'), id='C', description=''),
8
SeqRecord(Seq('CGCCCGCGAGGGCAATCAGGACGGATTTACGGAT'), id='D', description=''),
9
SeqRecord(Seq('CCGCCCACGCTCCCGTTTTCTTCCATACCTGTCC'), id='E', description='')
10
]
11
with open('test_out.fa', 'w') as f:
12
SeqIO.write(sequences, f, 'fasta')
Copied!

Operation on genomic formats (BigWig,etc.): bx-python

Operation on HDF5 files: h5py

Save data to an HDF5 file
1
import h5py
2
import numpy as np
3
# generate data
4
chroms = ['chr1', 'chr2', 'chr3']
5
chrom_sizes = {
6
'chr1': 15000,
7
'chr2': 12000,
8
'chr3': 11000
9
}
10
coverage = {}
11
counts = {}
12
for chrom, size in chrom_sizes.items():
13
coverage[chrom] = np.random.randint(10, 1000, size=size)
14
counts[chrom] = np.random.randint(1000, size=size)%coverage[chrom]
15
# save data to an HDF5 file
16
with h5py.File('dataset.h5', 'w') as f:
17
for chrom in chrom_sizes:
18
g = f.create_group(chrom)
19
g.create_dataset('coverage', data=coverage[chrom])
20
g.create_dataset('counts', data=counts[chrom])
Copied!
1
h5ls -r dataset.h5
Copied!
1
/ Group
2
/chr1 Group
3
/chr1/counts Dataset {15000}
4
/chr1/coverage Dataset {15000}
5
/chr2 Group
6
/chr2/counts Dataset {12000}
7
/chr2/coverage Dataset {12000}
8
/chr3 Group
9
/chr3/counts Dataset {11000}
10
/chr3/coverage Dataset {11000}
Copied!
Read data from an HDF file:
1
import h5py
2
# read data from an HDF5 file
3
with h5py.File('dataset.h5', 'r') as f:
4
coverage = {}
5
counts = {}
6
for chrom in f.keys():
7
coverage[chrom] = f[chrom + '/coverage'][:]
8
counts[chrom] = f[chrom + '/counts'][:]
Copied!

Mixed C/C++ and python programming: cython

1
import numpy as np
2
cimport numpy as np
3
cimport cython
4
from cython.parallel import prange
5
from cython.parallel cimport parallel
6
cimport openmp
7
8
@cython.boundscheck(False) # turn off bounds-checking for entire function
9
@cython.wraparound(False) # turn off negative index wrapping for entire function
10
def compute_mse_grad_linear_ard(np.ndarray[np.float64_t, ndim=1] w,
11
np.ndarray[np.float64_t, ndim=2] X1,
12
np.ndarray[np.float64_t, ndim=2] X2,
13
np.ndarray[np.float64_t, ndim=2] Kinv1,
14
np.ndarray[np.float64_t, ndim=2] K2,
15
np.ndarray[np.float64_t, ndim=2] a,
16
np.ndarray[np.float64_t, ndim=2] err,
17
np.ndarray[np.float64_t, ndim=2] mask=None):
18
'''Compute the gradients of MSE on the test samples with respect to relevance vector w.
19
:param w: 1D array of shape [n_features]
20
:return: gradients of MSE wrt. 2, 1D array of shape [n_features]
21
'''
22
cdef np.int64_t N1, N2, p
23
cdef np.int64_t k, i, j, m
24
N1 = X1.shape[0]
25
N2 = X2.shape[0]
26
p = X2.shape[1]
27
28
cdef np.ndarray[np.float64_t, ndim=2] K2Kinv1 = K2.dot(Kinv1)
29
cdef np.ndarray[np.float64_t, ndim=1] mse_grad = np.zeros_like(w)
30
31
#cdef np.ndarray[np.float64_t, ndim=3] K1_grad = np.zeros((p, N1, N1), dtype=np.float64)
32
#cdef np.ndarray[np.float64_t, ndim=3] K2_grad = np.zeros((p, N2, N1), dtype=np.float64)
33
#cdef np.ndarray[np.float64_t, ndim=3] K_grad = np.zeros((p, N2, N1), dtype=np.float64)
34
cdef np.int64_t max_n_threads = openmp.omp_get_max_threads()
35
cdef np.ndarray[np.float64_t, ndim=3] K1_grad = np.zeros((max_n_threads, N1, N1), dtype=np.float64)
36
cdef np.ndarray[np.float64_t, ndim=3] K2_grad = np.zeros((max_n_threads, N2, N1), dtype=np.float64)
37
cdef np.ndarray[np.float64_t, ndim=3] K_grad = np.zeros((max_n_threads, N1, N1), dtype=np.float64)
38
39
cdef np.int64_t thread_id
40
with nogil, parallel():
41
for k in prange(p):
42
thread_id = openmp.omp_get_thread_num()
43
# compute K1_grad
44
for i in range(N1):
45
for j in range(N1):
46
K1_grad[thread_id, i, j] = 2.0*w[k]*X1[i, k]*X1[j, k]
47
# compute K2_grad
48
for i in range(N2):
49
for j in range(N1):
50
K2_grad[thread_id, i, j] = 2.0*w[k]*X2[i, k]*X1[j, k]
51
# compute K_grad
52
for i in range(N2):
53
for j in range(N1):
54
K_grad[thread_id, i, j] = K2_grad[thread_id, i, j]
55
for m in range(N1):
56
K_grad[thread_id, i, j] += K2Kinv1[i, m]*K1_grad[thread_id, m, j]
57
# compute mse_grad
58
for i in range(N2):
59
for j in range(N1):
60
mse_grad[k] += err[i, 0]*K_grad[thread_id, i, j]*a[j, 0]
61
return mse_grad, K_grad
Copied!

Progress bar: tqdm

tqdm
tqdm_notebook

Example Python scripts

View a table in a pretty way

The original table is ugly:
1
head -n 15 metadata.tsv
Copied!
Output:
1
File accession File format Output type Experiment accession Assay Biosample term id
2
ENCFF983DFB fastq reads ENCSR429XTR ChIP-seq EFO:0002067
3
ENCFF590TBW fastq reads ENCSR429XTR ChIP-seq EFO:0002067
4
ENCFF258RWG bam unfiltered alignments ENCSR429XTR ChIP-seq EFO:0002067
5
ENCFF468LRV bam unfiltered alignments ENCSR429XTR ChIP-seq EFO:0002067
6
ENCFF216EBS bam alignments ENCSR429XTR ChIP-seq EFO:0002067
7
ENCFF232QFN bam unfiltered alignments ENCSR429XTR ChIP-seq EFO:0002067
8
ENCFF682NGE bam alignments ENCSR429XTR ChIP-seq EFO:0002067
9
ENCFF328UKA bam unfiltered alignments ENCSR429XTR ChIP-seq EFO:0002067
10
ENCFF165COO bam alignments ENCSR429XTR ChIP-seq EFO:0002067
11
ENCFF466OLG bam alignments ENCSR429XTR ChIP-seq EFO:0002067
12
ENCFF595HIY bigBed narrowPeak peaks ENCSR429XTR ChIP-seq EFO:0002067
13
ENCFF494CKB bigWig fold change over control ENCSR429XTR ChIP-seq EFO:0002067
14
ENCFF308BXW bigWig fold change over control ENCSR429XTR ChIP-seq EFO:0002067
15
ENCFF368IHM bed narrowPeak peaks ENCSR429XTR ChIP-seq EFO:0002067
Copied!
Now display the table more clearly:
1
head -n 15 metadata.tsv | tvi -d $'\t' -j center
Copied!
Output:
1
File accession File format Output type Experiment accession Assay Biosample term id
2
ENCFF983DFB fastq reads ENCSR429XTR ChIP-seq EFO:0002067
3
ENCFF590TBW fastq reads ENCSR429XTR ChIP-seq EFO:0002067
4
ENCFF258RWG bam unfiltered alignments ENCSR429XTR ChIP-seq EFO:0002067
5
ENCFF468LRV bam unfiltered alignments ENCSR429XTR ChIP-seq EFO:0002067
6
ENCFF216EBS bam alignments ENCSR429XTR ChIP-seq EFO:0002067
7
ENCFF232QFN bam unfiltered alignments ENCSR429XTR ChIP-seq EFO:0002067
8
ENCFF682NGE bam alignments ENCSR429XTR ChIP-seq EFO:0002067
9
ENCFF328UKA bam unfiltered alignments ENCSR429XTR ChIP-seq EFO:0002067
10
ENCFF165COO bam alignments ENCSR429XTR ChIP-seq EFO:0002067
11
ENCFF466OLG bam alignments ENCSR429XTR ChIP-seq EFO:0002067
12
ENCFF595HIY bigBed narrowPeak peaks ENCSR429XTR ChIP-seq EFO:0002067
13
ENCFF494CKB bigWig fold change over control ENCSR429XTR ChIP-seq EFO:0002067
14
ENCFF308BXW bigWig fold change over control ENCSR429XTR ChIP-seq EFO:0002067
15
ENCFF368IHM bed narrowPeak peaks ENCSR429XTR ChIP-seq EFO:0002067
Copied!
You can also get some help by typing tvi -h:
1
usage: tvi [-h] [-d DELIMITER] [-j {left,right,center}] [-s SEPARATOR]
2
[infile]
3
4
Print tables pretty
5
6
positional arguments:
7
infile input file, default is stdin
8
9
optional arguments:
10
-h, --help show this help message and exit
11
-d DELIMITER delimiter of fields of input. Default is white space.
12
-j {left,right,center}
13
justification, either left, right or center. Default
14
is left
15
-s SEPARATOR separator of fields in output
Copied!
tvi.py
1
#! /usr/bin/env python
2
3
import sys
4
import argparse
5
import os