【问题标题】:Extract specific rows based on the set cut-off values in columns根据列中设置的截止值提取特定行
【发布时间】:2017-09-20 19:06:21
【问题描述】:

我有一个 TAB 分隔的 .txt 文件,看起来像这样。

Gene_name   A   B   C   D   E   F
Gene1      1    0   5   2   0   0
Gene2      4    45  0   0   32  1
Gene3      0    23  0   4   0   54
Gene4     12    0   6   8   7   4
Gene5     4     0   0   6   0   7
Gene6     0     6   8   0   0   5
Gene7     13    45  64  234 0   6
Gene8     11    6   0   7   7   9
Gene9      6    0   12  34  0   11
Gene10    23    4   6   7   89  0

我想提取至少 3 列的值 > 0 的行。 我如何使用熊猫来做到这一点?我对如何在 .txt 文件中使用条件一无所知。

非常感谢!


更新:添加到这个问题,我如何分析这个条件的特定列..假设我查看 A、C、E 和 F 列,然后提取这些列中至少有 3 个具有值的行 > 5.

干杯!

【问题讨论】:

  • 一旦你用 pandas 加载它们,它们就不再是 txt 文件,而是变成了DataFrames。如果您遵循有关 pandas 的教程/指南,您将了解如何填充数据。
  • 感谢您编辑这个问题,只是想知道您是如何获得表格形式的东西的?谢谢..
  • @Edin 你复制数据并按 ctrl+K。

标签: python pandas dataframe extract


【解决方案1】:
df = pd.read_csv(filename, delim_whitespace=True)

In [22]: df[df.select_dtypes(['number']).gt(0).sum(axis=1).ge(3)]
Out[22]:
  Gene_name   A   B   C    D   E   F
0     Gene1   1   0   5    2   0   0
1     Gene2   4  45   0    0  32   1
2     Gene3   0  23   0    4   0  54
3     Gene4  12   0   6    8   7   4
4     Gene5   4   0   0    6   0   7
5     Gene6   0   6   8    0   0   5
6     Gene7  13  45  64  234   0   6
7     Gene8  11   6   0    7   7   9
8     Gene9   6   0  12   34   0  11
9    Gene10  23   4   6    7  89   0

一些解释:

In [25]: df.select_dtypes(['number']).gt(0)
Out[25]:
       A      B      C      D      E      F
0   True  False   True   True  False  False
1   True   True  False  False   True   True
2  False   True  False   True  False   True
3   True  False   True   True   True   True
4   True  False  False   True  False   True
5  False   True   True  False  False   True
6   True   True   True   True  False   True
7   True   True  False   True   True   True
8   True  False   True   True  False   True
9   True   True   True   True   True  False

In [26]: df.select_dtypes(['number']).gt(0).sum(axis=1)
Out[26]:
0    3
1    4
2    3
3    5
4    3
5    3
6    5
7    5
8    4
9    5
dtype: int64

【讨论】:

    【解决方案2】:

    使用运算符(作为 Max 答案的补充):

    mask = (df.iloc[:, 1:] > 0).sum(1) >= 3    
    mask
    
    0    True
    1    True
    2    True
    3    True
    4    True
    5    True
    6    True
    7    True
    8    True
    9    True
    dtype: bool
    
    df[mask] 
      Gene_name   A   B   C    D   E   F
    0     Gene1   1   0   5    2   0   0
    1     Gene2   4  45   0    0  32   1
    2     Gene3   0  23   0    4   0  54
    3     Gene4  12   0   6    8   7   4
    4     Gene5   4   0   0    6   0   7
    5     Gene6   0   6   8    0   0   5
    6     Gene7  13  45  64  234   0   6
    7     Gene8  11   6   0    7   7   9
    8     Gene9   6   0  12   34   0  11
    9    Gene10  23   4   6    7  89   0
    

    同样,查询所有具有 5 个或更多正值的行:

    df[(df.iloc[:, 1:] > 0).sum(1) >= 5]
    
      Gene_name   A   B   C    D   E  F
    3     Gene4  12   0   6    8   7  4
    6     Gene7  13  45  64  234   0  6
    7     Gene8  11   6   0    7   7  9
    9    Gene10  23   4   6    7  89  0
    

    【讨论】:

    • @coldspeed 只是添加到这个问题,我如何分析这个条件的特定列..假设我查看 A、C、E 和 F 列,然后提取至少有 3 行这些列中的值 >0。
    • 道歉我对此很天真,但是当我运行它时: import pandas as pd df = pd.read_csv('python1.txt', sep='\t') df2 = df[['A ', 'C', 'E', 'F']]; df2[(df2.iloc[:, 1:] > 0).sum(1) >= 3] print(df2) 我得到了所有四列都有值的行。我希望只得到那些行至少有三列(A、C、E、F)的值>0
    • @Edin 对不起,我是df2 = df[['A', 'C', 'E', 'F']]; df2[(df2 > 0).sum(1) >= 3]
    • @coldspeed 无论这些列中的值如何,它仍然会为我提供所有行,当我将“>= 3”更改为“>= 5”时它甚至都不会打扰。
    • @Edin 根据您的更新:df2 = df[['A', 'C', 'E', 'F']]; df2[(df2 > 5).sum(1) >= 3]
    【解决方案3】:

    小猪退出 @MaxU 解决方案,我喜欢继续将“gene_name”放入索引中,而不用担心所有索引切片:

    df = pd.read_csv(tfile, delim_whitespace=True, index_col=0)
    df[df.gt(0).sum(1).ge(3)]
    

    编辑问题更新:

    df[df[['A','C','E','F']].gt(5).sum(1).ge(3)]
    

    输出:

                A   B   C    D   E   F
    Gene_name                         
    Gene4      12   0   6    8   7   4
    Gene7      13  45  64  234   0   6
    Gene8      11   6   0    7   7   9
    Gene9       6   0  12   34   0  11
    Gene10     23   4   6    7  89   0
    

    【讨论】:

    • 好主意!它使解决方案看起来很漂亮!
    • @Scott Boston 你能帮忙解决更新的问题吗:
    • @Edin 查看解决方案的更新。这就是你要找的吗?
    • @ScottBoston 是的,效果很好。能否请您简要解释一下这段代码是如何工作的,下次我自己写会很有帮助。
    • 确定它使用 df[['A','C','E','F']] 基本上是对原始数据帧进行列过滤。然后我检查每个值是否大于 5,返回 True 和 False 的数据帧,然后我对每一行(axis = 1)求和并检查该总和是否大于或等于 5。返回为系列原始数据帧的行索引作为系列的索引。接下来,在原始数据帧上使用布尔索引,我将该系列传递回数据帧以在系列为真的那些行上进行选择。把那句话分成几部分。从内部 df 开始。
    猜你喜欢
    • 2020-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多