无法从熊猫数据框中提取正确的列

时间:2018-12-30 21:37:19

标签: python pandas dataframe

我正在创建一个脚本,通过跟踪测试数据集中的错误来编辑DNA序列比对。我的目标是跟踪包含低于和超过特定阈值的终止密码子的列。例如,如果一列(包含3个碱基或一个密码子)包含“ TAA”,“ TGA”或“ TAG”,并且如果超过40%的样品包含该列中的那些终止密码子,我想保留记录在单独的excel文件(我可以创建)中,因为这些列将被删除。如果少于40%的样本在一列中包含终止密码子,我将分别对其进行跟踪,因为需要对其进行编辑。

我的数据框看起来像这样(我在这里添加了“ /”只是为了更容易地在此处显示密码子):

    1    2  3    4 ... 1000
S1 TAA/TAA/TGA/CCC/.../TGA
S2 ATG/-AT/TAG/---/.../TGA
S3 ATG/TAA/-CC/--T/.../TAA
S4 ATG/TAA/GTA/CCC/.../TAA
S5 ATG/-AT/---/---/.../TAG
S6 ATG/TAA/-CC/--T/.../TAG
S7 ATG/TAA/GTA/CCC/.../CCC
S8 ATG/-AT/---/---/.../CCC
S9 ATG/TAA/-CC/--T/.../CCC
S10 ATG/TAA/-CC/--T/.../CCC

我可以轻松地提取带有缺口的列(包含“ ---”),并且能够跟踪终止密码子超过40%的列,但无法跟踪包含少于40%的列,这是因为正在分别遍历这3个密码子。例如,如果我有10个样本,如果第1列中少于4个样本包含“ TAA”或“ TGA”或“ TAG”(在任何组合中),我将保留该记录,并将终止密码更改为“ ---在最终编辑的数据框中。但是,当每个终止密码子出现的次数少于4次时,我的脚本将对它们进行单独处理,并向我显示包含超过40%终止密码子的列,因为我无法弄清楚如何对所有三个密码子求和。一共。

df # (loaded earlier from a large script)
df_track = pd.DataFrame() # make new df to track less than 40% stop codons in columns
codon = ["TAA","TGA","TAG"]
def track_lessthan40(df, codon, 0.4):
    num_rows = len(df)
    change = [col for col in df.columns \
        if sum(df[col] == codon[0]) > 0 or sum(df[col] == codon[1]) > 0 \
        or sum(df[col] == codon[2]) > 0 \
        and sum(df[col] == codon[0]) \
        and sum(df[col] == codon[1]) \
        and sum(df[col] == codon[2]) < round(num_rows*0.4, 2)]

df_change = df[change]
print(df_change)

我期望的是

df_change

    1  3
S1 TAA/TGA
S2 ATG/TAG
S3 ATG/-CC
S4 ATG/GTA
S5 ATG/---
S6 ATG/-CC
S7 ATG/GTA
S8 ATG/---
S9 ATG/-CC
S10 ATG/-CC

我得到的。

    1  3  ... 1000
S1 TAA/TGA/.../TGA
S2 ATG/TAG/.../TGA
S3 ATG/-CC/.../TAA
S4 ATG/GTA/.../TAA
S5 ATG/---/.../TAG
S6 ATG/-CC/.../TAG
S7 ATG/GTA/.../CCC
S8 ATG/---/.../CCC
S9 ATG/-CC/.../CCC
S10 ATG/-CC/.../CCC

最后一栏显示,但不应显示。仅当我希望在40%以上的样本中出现终止密码子的列时,才应在其他脚本中对其进行跟踪。 有关如何执行此操作的任何想法?谢谢!

2 个答案:

答案 0 :(得分:2)

IIUC df.isin(codon).sum()/len(df) <= 0.4 输出

#    1       True
#  2        False
# 3          True
#   4        True
# 1000      False

,您可以选择以下列:

df.loc[:, df.isin(codon).sum()/len(df) <= 0.4]

使用pd.isin检查列中是否有任何一个终止密码子,求和以计算其为真的次数,然后除以数据框的长度得到百分比。

答案 1 :(得分:1)

在您的示例代码组成和所使用的df之间似乎可能存在差异。乔恩(Jon)稍作调整的示例和我的脚本适用于您的示例(参见图片)。

enter image description here

# my clunky example
import pandas as pd
csv = '/Users/<USER>/PycharmProjects/stackoverflow/gattaka.text'

df = pd.read_table(csv, sep='/')

df_track = pd.DataFrame()  # make new df to track less than 40% stop codons in columns
codon = ["TAA", "TGA", "TAG"]

for column in df.columns:
    col_length = len(df[column])
    col_list = df[column].tolist()

    sum_stopper = 0
    for gene in col_list:
        if gene in codon:
            sum_stopper += 1

    if sum_stopper == 0:
        break

    elif sum_stopper <= (0.4 * col_length):
        col_series = pd.Series(col_list, name=column)
        df_track[column] = col_series

print(df_track)
print('------')

# Jon's adjusted, pretty, concise and pythonic example
df_track = df.loc[:, (df.isin(codon).sum()/len(df) <= 0.4) & (df.isin(codon).sum() > 0)]