【问题标题】:Counting elements based on placement in dataframe根据数据框中的位置计算元素
【发布时间】:2021-11-01 07:47:58
【问题描述】:

在下面,我有一个表,其中 TST1TST5 的列不能采用任何值或以下之一:NOT_DONEINCOMPUNTESTED30354045@ 987654330@

我需要计算从下表中验证的元素(行)的数量。

当最右边的值介于 30 和 50 之间(由 5 分隔,因此 30、35、40...)时,元素被认为是已验证。这意味着如果该行对于所有TST1TST5 都没有值,则不计算任何内容。如果在 NOT_DONE INCOMPUNTESTED 的左侧找到数值,则不会对其进行验证。

换句话说,我需要从右到左计算每一行。

例如,从下表中,只有 6 个元素被认为是经过验证的。

最后,我需要计算其中有多少属于 A 组或 B 组。

我最初解决这个问题的想法是创建一个包含所有经过验证的元素的新列,但我真的不知道该怎么做。

我正在使用 python 2.7 和 pandas 0.24.2。我是新手,非常感谢任何帮助或指导。

+-------+----------+----------+----------+--------+----------+
| Group | TST1     | TST2     | TST3     | TST4   | TST5     |
+-------+----------+----------+----------+--------+----------+
| A     |          | NOT_DONE |          |        | 50       |
+-------+----------+----------+----------+--------+----------+
| A     |          |          | 35       |        |          |
+-------+----------+----------+----------+--------+----------+
| B     |          |          |          |        |          |
+-------+----------+----------+----------+--------+----------+
| A     |          |          | INCOMP   |        |          |
+-------+----------+----------+----------+--------+----------+
| B     | UNTESTED |          | 50       | INCOMP |          |
+-------+----------+----------+----------+--------+----------+
| B     |          |          |          |        |          |
+-------+----------+----------+----------+--------+----------+
| B     |          | 30       |          |        |          |
+-------+----------+----------+----------+--------+----------+
| A     |          | INCOMP   | 40       |        |          |
+-------+----------+----------+----------+--------+----------+
| B     |          |          |          |        | UNTESTED |
+-------+----------+----------+----------+--------+----------+
| A     |          |          |          |        |          |
+-------+----------+----------+----------+--------+----------+
| B     |          | INCOMP   |          |        |          |
+-------+----------+----------+----------+--------+----------+
| A     |          |          |          |        |          |
+-------+----------+----------+----------+--------+----------+
| B     |          | 50       |          |        |          |
+-------+----------+----------+----------+--------+----------+
| B     |          |          | UNTESTED | 35     | NOT_DONE |
+-------+----------+----------+----------+--------+----------+
| B     |          |          |          |        |          |
+-------+----------+----------+----------+--------+----------+
| A     |          | 40       |          | INCOMP |          |
+-------+----------+----------+----------+--------+----------+
| A     |          |          |          | 30     |          |
+-------+----------+----------+----------+--------+----------+
| B     |          |          |          |        |          |
+-------+----------+----------+----------+--------+----------+
| B     |          | NOT_DONE |          | 30     | NOT_DONE |
+-------+----------+----------+----------+--------+----------+

编辑: 这是我尝试过的,但它计算所有显示数值的行,而不是最右边的值为数字的行。我真的不知道如何选择从右边开始。

    filter1 = df.loc[:, 'TST1':'TST5']\
        .apply(lambda x: x.astype(str).str.match(r'\d+\.*\d*'), axis=0)\
        .any(axis=1)
    number_validated = filter1.sum()
    print "Number of validated items: ", number_validated

预期的输出应该只是一个简短的文本摘要:

Number of validated items: 5
Number of group A validated items: 4
Number of group B validated items: 2

【问题讨论】:

    标签: python pandas python-2.7


    【解决方案1】:

    另一个选项,在 python 2.7.18 和 pandas 0.24.2 上测试过(虽然它在 python 3 中运行良好):

    1. 使用ffill 提取最右边的值并使用to_numeric 将它们强制转换为数字:

      rightmost = df.filter(like='TST').ffill(axis='columns').iloc[:, -1]
      rightmost = pd.to_numeric(rightmost, errors='coerce')
      
      # 0      NaN
      # 1     35.0
      # 2      NaN
      # 3      NaN
      # 4      NaN
      # 5      NaN
      # 6     30.0
      # 7     40.0
      # 8      NaN
      # 9      NaN
      # 10     NaN
      # 11     NaN
      # 12    50.0
      # 13     NaN
      # 14     NaN
      # 15     NaN
      # 16    30.0
      # 17     NaN
      # 18     NaN
      # Name: TST5, dtype: float64
      
    2. 然后groupby Group 并检查它们是否是between 30 和 50(含):

      valid = rightmost.groupby(df.Group).apply(
          lambda g: g.between(30, 50, inclusive='both').sum()
      ).to_frame('Valid')
      
      #        Valid
      # Group       
      # A          3
      # B          2
      

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-11
      • 2018-01-29
      • 2015-06-28
      • 2014-02-14
      • 2021-02-27
      • 2022-09-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多