【问题标题】:Unable to extract the correct columns from a pandas dataframe无法从熊猫数据框中提取正确的列
【发布时间】:2018-12-30 21:37:19
【问题描述】:

我正在创建一个脚本,通过跟踪测试数据集中的错误来编辑 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% 的样本中出现终止密码子的列时,才应在我的其他脚本中对其进行跟踪。 关于如何做到这一点的任何想法?谢谢!

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    IIUC df.isin(codon).sum()/len(df) &lt;= 0.4 输出

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

    您可以像这样选择列:

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

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

    【讨论】:

    • 我试过了,但它为我返回了整个 df,而不是只包含我需要的列的新 df。这应该在我的循环之后进行吗?我只是在没有我的 for 循环的情况下尝试了你单独输入的内容。
    • 嗯,我正在测试的示例数据框实际上有 1000 列,哈哈,我正在把它们都找回来。
    • 它正在为我转换整个数据帧......如果我在我的函数中使用那行代码是否不正确?我在 for 循环中注释掉了我的所有行并使用了你的……也许我写错了。
    【解决方案2】:

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

    # 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)]
    

    【讨论】:

    • 它正在做相反的事情,它给了我一个没有这些列的表,但我必须单独记录这些列(在 df_change 中),然后我在新数据框中将停靠点编辑为间隙所以我不会丢失整个专栏。我删除整个列的唯一一次是终止密码子出现在超过 40% 的样本中。该脚本还将我所有的示例名称更改为索引大声笑。
    • 我有点困惑。我认为您需要答案中显示的格式的数据为“我期望的:”。我对代码做了一些更改。 1. 不包含停止器的列被忽略 2. 现在只返回超过 40% 停止器的列 3. 将系列附加到 df - 我希望解决“索引”转换问题
    • 抱歉,我有两组表。在我打开的这个问题中,我想获取在少于 40% 的样本中出现终止密码子的所有列(因此它们存在但不超过 40%,如果超过 40%,我有一个单独的代码要保留在一个单独的文件中)。原因是,如果它们存在但少于 40%,我会将这些止损编辑为空白。如果它们出现在超过 40% 的样本中,我会删除整列。所以我所展示的是当它低于 40% 时我期望获得的。如果超过 40%,我预计只会出现最后一列。
    • 我再次尝试了您的代码,但它不起作用,只是恢复了空数据帧。它对我的脚本有点作用,我只需要一种方法来计算一列中的所有 3 个终止密码子,因为它们的总数不到 40% 的样本中。
    • 在这个版本中,我添加了 Jon 和我使用的文本文件。我无能为力,祝你好运。
    猜你喜欢
    • 2018-07-06
    • 1970-01-01
    • 2019-03-24
    • 1970-01-01
    • 1970-01-01
    • 2017-06-26
    • 1970-01-01
    • 2021-05-25
    • 2017-07-03
    相关资源
    最近更新 更多