查找每列中的字母数

时间:2018-03-24 20:04:56

标签: python pandas bioinformatics biopython

我需要在每列中找到字母数,如下所示:

String: ATCG
        TGCA
        AAGC
        GCAT

string是一个系列。

我需要编写一个程序来获得以下内容:

  0 1 2 3
A 2 1 1 1
T 1 1 0 1
C 0 1 2 1
G 1 1 1 1 

我编写了以下代码但是我在最后的0索引和列中获取了一行(列索引450,实际列号为451),并带有nan值。我不应该得到行或列451.我只需要450列。

f = zip(*string)
counts = [{letter: column.count(letter) for letter in column} for column in 
f]
counts=pd.DataFrame(counts).transpose()
print(counts)
counts = counts.drop(counts.columns[[450]], axis =1)

任何人都可以帮我理解这个问题吗?

2 个答案:

答案 0 :(得分:3)

这是一种可以实现逻辑的方法。如果需要,您可以通过WITH CTE AS ( SELECT street, street_number, MAX(built_year) AS maxBuiltYear FROM House GROUP BY street, street_number HAVING COUNT(*)>1) UPDATE House SET built_year = maxBuiltYear FROM House as h INNER JOIN CTE as c ON c.street = h.street and c.street_number = h.street_number WHERE built_year = 0; 将系列变为列表。

lst = s.tolist()

<强>结果

lst = ['ATCG', 'TGCA', 'AAGC', 'GCAT']

arr = [[i.count(x) for i in zip(*lst)] for x in ('ATCG')]

res = pd.DataFrame(arr, index=list('ATCG'))

<强>解释

  • 在列表推导中,首先通过依次迭代每个字符串的第一,第二,第三和第四个元素来处理列。
  • 通过顺序迭代'ATCG'来处理第二行。
  • 这会生成一个列表,可以直接输入 0 1 2 3 A 2 1 1 1 T 1 1 0 1 C 0 1 2 1 G 1 1 1 1

答案 1 :(得分:2)

使用Series.value_counts()

>>> s = pd.Series(['ATCG', 'TGCA', 'AAGC', 'GCAT'])

>>> s.str.join('|').str.split('|', expand=True)\
...     .apply(lambda row: row.value_counts(), axis=0)\
...     .fillna(0.)\
...     .astype(int)
   0  1  2  3
A  2  1  1  1
C  0  1  2  1
G  1  1  1  1
T  1  1  0  1

我不确定您想要对索引进行逻辑排序,但您可以在此结果上调用.reindex().sort_index()

第一行s.str.join('|').str.split('|', expand=True)为您提供“扩展”版本

   0  1  2  3
0  A  T  C  G
1  T  G  C  A
2  A  A  G  C
3  G  C  A  T

应该比在每行调用pd.Series(list(x)) ...更快。