比较文件的连续列和 return 不匹配元素的数量
Compare consecutive columns of a file and return the number of non-matching elements
我有一个如下所示的文本文件:
# sampleID HGDP00511 HGDP00511 HGDP00512 HGDP00512 HGDP00513 HGDP00513
M rs4124251 0 0 A G 0 A
M rs6650104 0 A C T 0 0
M rs12184279 0 0 G A T 0
我想比较连续的列和return匹配元素的数量。我想在 Python 中执行此操作。早些时候,我使用 Bash 和 AWK(shell 脚本)完成了它,但它非常慢,因为我有大量数据要处理。我相信 Python 会是一个更快的解决方案。但是,我是 Python 的新手,我已经有了这样的东西:
for line in open("phased.txt"):
columns = line.split("\t")
for i in range(len(columns)-1):
a = columns[i+3]
b = columns[i+4]
for j in range(len(a)):
if a[j] != b[j]:
print j
这显然不起作用。由于我是 Python 的新手,我真的不知道要进行哪些更改才能使其正常工作。 (这是完全错误的代码,我想我可以使用 difflib 等。但是,我以前从未在 Python 中熟练地编码,所以,持怀疑态度继续)
我想比较文件中每一列(从第三列开始)中不匹配元素的数量 return 与文件中的所有其他列。我总共有 828 列。因此我需要 828*828 个输出。 (你可以想象一个 n*n 矩阵,其中第 (i,j) 个元素是它们之间不匹配元素的数量。如果是上面的代码片段,我想要的输出是:
3 4: 1
3 5: 3
3 6: 3
......
4 6: 3
..etc
如有任何帮助,我们将不胜感激。谢谢
我强烈建议您为此使用 pandas 而不是编写自己的代码:
import numpy as np
import pandas as pd
df = pd.read_csv("phased.txt")
match_counts = {(i,j):
np.sum(df[df.columns[i]] != df[df.columns[j]])
for i in range(3,len(df.columns))
for j in range(3,len(df.columns))}
match_counts
{(6, 4): 3,
(4, 7): 2,
(4, 4): 0,
(4, 3): 3,
(6, 6): 0,
(4, 5): 3,
(5, 4): 3,
(3, 5): 3,
(7, 7): 0,
(7, 5): 3,
(3, 7): 2,
(6, 5): 3,
(5, 5): 0,
(7, 4): 2,
(5, 3): 3,
(6, 7): 2,
(4, 6): 3,
(7, 6): 2,
(5, 7): 3,
(6, 3): 2,
(5, 6): 3,
(3, 6): 2,
(3, 3): 0,
(7, 3): 2,
(3, 4): 3}
解决此问题的纯本机 python 库方法 - 让我们知道它与 bash 828 x 828 的比较应该是在公园散步。
元素列数:
出于简单和说明的目的,我特意在翻转序列的步骤中写了这篇文章 - 您可以通过更改逻辑或使用 class 对象、函数装饰器等来改进它...
代码Python 2.7:
shiftcol = 2 # shift columns as first two are to be ignored
with open('phased.txt') as f:
data = [x.strip().split('\t')[shiftcol:] for x in f.readlines()][1:]
# Step 1: Flipping the data first
flip = []
for idx, rows in enumerate(data):
for i in range(len(rows)):
if len(flip) <= i:
flip.append([])
flip[i].append(rows[i])
# Step 2: counts store in temp dictionary
for idx, v in enumerate(flip):
for e in v:
tmp = {}
for i, z in enumerate(flip):
if i != idx and e != '0':
# Dictionary to store results
if i+1 not in tmp: # note has_key will be deprecated
tmp[i+1] = {'match': 0, 'notma': 0}
tmp[i+1]['match'] += z.count(e)
tmp[i+1]['notma'] += len([x for x in z if x != e])
# results compensate for column shift..
for key, count in tmp.iteritems():
print idx+shiftcol+1, key+shiftcol, ': ', count
示例输出
>>> 3 4 : {'match': 0, 'notma': 3}
>>> 3 5 : {'match': 0, 'notma': 3}
>>> 3 6 : {'match': 2, 'notma': 1}
>>> 3 7 : {'match': 2, 'notma': 1}
>>> 3 3 : {'match': 1, 'notma': 2}
>>> 3 4 : {'match': 1, 'notma': 2}
>>> 3 5 : {'match': 1, 'notma': 2}
我有一个如下所示的文本文件:
# sampleID HGDP00511 HGDP00511 HGDP00512 HGDP00512 HGDP00513 HGDP00513
M rs4124251 0 0 A G 0 A
M rs6650104 0 A C T 0 0
M rs12184279 0 0 G A T 0
我想比较连续的列和return匹配元素的数量。我想在 Python 中执行此操作。早些时候,我使用 Bash 和 AWK(shell 脚本)完成了它,但它非常慢,因为我有大量数据要处理。我相信 Python 会是一个更快的解决方案。但是,我是 Python 的新手,我已经有了这样的东西:
for line in open("phased.txt"):
columns = line.split("\t")
for i in range(len(columns)-1):
a = columns[i+3]
b = columns[i+4]
for j in range(len(a)):
if a[j] != b[j]:
print j
这显然不起作用。由于我是 Python 的新手,我真的不知道要进行哪些更改才能使其正常工作。 (这是完全错误的代码,我想我可以使用 difflib 等。但是,我以前从未在 Python 中熟练地编码,所以,持怀疑态度继续)
我想比较文件中每一列(从第三列开始)中不匹配元素的数量 return 与文件中的所有其他列。我总共有 828 列。因此我需要 828*828 个输出。 (你可以想象一个 n*n 矩阵,其中第 (i,j) 个元素是它们之间不匹配元素的数量。如果是上面的代码片段,我想要的输出是:
3 4: 1
3 5: 3
3 6: 3
......
4 6: 3
..etc
如有任何帮助,我们将不胜感激。谢谢
我强烈建议您为此使用 pandas 而不是编写自己的代码:
import numpy as np
import pandas as pd
df = pd.read_csv("phased.txt")
match_counts = {(i,j):
np.sum(df[df.columns[i]] != df[df.columns[j]])
for i in range(3,len(df.columns))
for j in range(3,len(df.columns))}
match_counts
{(6, 4): 3,
(4, 7): 2,
(4, 4): 0,
(4, 3): 3,
(6, 6): 0,
(4, 5): 3,
(5, 4): 3,
(3, 5): 3,
(7, 7): 0,
(7, 5): 3,
(3, 7): 2,
(6, 5): 3,
(5, 5): 0,
(7, 4): 2,
(5, 3): 3,
(6, 7): 2,
(4, 6): 3,
(7, 6): 2,
(5, 7): 3,
(6, 3): 2,
(5, 6): 3,
(3, 6): 2,
(3, 3): 0,
(7, 3): 2,
(3, 4): 3}
解决此问题的纯本机 python 库方法 - 让我们知道它与 bash 828 x 828 的比较应该是在公园散步。
元素列数:
出于简单和说明的目的,我特意在翻转序列的步骤中写了这篇文章 - 您可以通过更改逻辑或使用 class 对象、函数装饰器等来改进它...
代码Python 2.7:
shiftcol = 2 # shift columns as first two are to be ignored
with open('phased.txt') as f:
data = [x.strip().split('\t')[shiftcol:] for x in f.readlines()][1:]
# Step 1: Flipping the data first
flip = []
for idx, rows in enumerate(data):
for i in range(len(rows)):
if len(flip) <= i:
flip.append([])
flip[i].append(rows[i])
# Step 2: counts store in temp dictionary
for idx, v in enumerate(flip):
for e in v:
tmp = {}
for i, z in enumerate(flip):
if i != idx and e != '0':
# Dictionary to store results
if i+1 not in tmp: # note has_key will be deprecated
tmp[i+1] = {'match': 0, 'notma': 0}
tmp[i+1]['match'] += z.count(e)
tmp[i+1]['notma'] += len([x for x in z if x != e])
# results compensate for column shift..
for key, count in tmp.iteritems():
print idx+shiftcol+1, key+shiftcol, ': ', count
示例输出
>>> 3 4 : {'match': 0, 'notma': 3}
>>> 3 5 : {'match': 0, 'notma': 3}
>>> 3 6 : {'match': 2, 'notma': 1}
>>> 3 7 : {'match': 2, 'notma': 1}
>>> 3 3 : {'match': 1, 'notma': 2}
>>> 3 4 : {'match': 1, 'notma': 2}
>>> 3 5 : {'match': 1, 'notma': 2}