【问题标题】:Pandas dataframe/csv pivot table, how to eliminate series based on first or last values?Pandas 数据框/csv 数据透视表,如何根据第一个或最后一个值消除系列?
【发布时间】:2017-08-17 01:50:26
【问题描述】:

我将数据保存在 pandas 数据框中(通过 pd.read_csv 由 csv 文件制成),目前分为 3 列。这些信息会告诉您患者 ID、自他们第一次就诊以来的天数以及他们在医院的测试得分。

| Patient | Days | Score |
|---------|------|-------|
|       1 |    0 |    30 |
|       1 |  100 |    30 |
|       1 |  150 |    29 |
|       2 |    0 |    24 |
|       2 |   45 |    22 |
|       2 |   95 |    20 |
|       2 |  130 |    16 |
|       3 |    0 |    30 |
|       3 |  125 |    29 |
|       3 |  225 |    28 |

我想扫描数据,只要患者在第一次到医院就诊的日期得分低于 28,就将该患者从数据框中完全删除。 (或者,创建一个缺少所有这些患者的新数据框)。

对于上面的数据,这意味着移除患者“2”,给我们留下最终数据

| Patient | Days | Score |
|---------|------|-------|
|       1 |    0 |    30 |
|       1 |  100 |    30 |
|       1 |  150 |    29 |
|       3 |    0 |    30 |
|       3 |  125 |    29 |
|       3 |  225 |    28 |

我之前尝试将 Dataframe 转换为 pivot_table,但在索引方面遇到了一些问题。总共有大约4,000名患者。使用 Pandas/NumPy 最干净的方法是什么?

【问题讨论】:

    标签: python-3.x pandas numpy dataframe


    【解决方案1】:
    In [9]: df[df.groupby('Patient')['Score'].transform('first').ge(28)]
    Out[9]:
       Patient  Days  Score
    0        1     0     30
    1        1   100     30
    2        1   150     29
    7        3     0     30
    8        3   125     29
    9        3   225     28
    

    或:

    In [20]: df.groupby('Patient').filter(lambda x: x.iloc[0, df.columns.get_loc('Score')] >= 28)
    Out[20]:
       Patient  Days  Score
    0        1     0     30
    1        1   100     30
    2        1   150     29
    7        3     0     30
    8        3   125     29
    9        3   225     28
    

    时间为 100.000 行 DF:

    In [22]: df = pd.concat([df] * 10**4, ignore_index=True)
    
    In [23]: df.shape
    Out[23]: (100000, 3)
    
    In [24]: %timeit df[df.groupby('Patient')['Score'].transform('first').ge(28)]
    16.8 ms ± 617 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
    
    In [25]: %timeit df.groupby('Patient').filter(lambda x: x.iloc[0, df.columns.get_loc('Score')] >= 28)
    49.9 ms ± 1.34 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
    

    【讨论】:

    • @saxophone37,很高兴我能帮上忙 :)
    • 在 .transform('first').ge(28) 中,ge 代表什么?有没有一种简单的方法可以将其用于其他操作?即如果 ge 大于/等于,是否有小于版本可以用来删除小于数字的项目?我可以将其他方程/函数放在 () 而不是 28 中吗?再次感谢。
    • @saxophone37, .ge() - “大于或等于” - 和>=一样,所以我们可以这样做:df[df.groupby('Patient')['Score'].transform('first') >= 28]
    猜你喜欢
    • 2020-10-10
    • 1970-01-01
    • 2021-11-08
    • 1970-01-01
    • 2018-12-12
    • 1970-01-01
    • 1970-01-01
    • 2017-07-12
    • 2020-11-26
    相关资源
    最近更新 更多