python - 如何根据给定条件 pandas/python 删除 *some* 行
问题描述
我正在使用 Pandas 中的数据集,我想根据给定条件删除一些行。我的数据集中有一列是参与者的合并症数量,可能的值为 0、1、2、3。数据集大约有 100 万行(和 30 个其他列),大约 50 万参与者 = 0 合并症,约 300,000 名参与者 = 1 种合并症,约 130,000 名参与者 = 2 种合并症,约 75,000 名参与者 = 3 种合并症。我想根据他们的合并症值随机删除参与者组,例如,删除 200k 与 0 合并症,100k 与 1 合并症。我知道如果想放弃所有合并症数量给定的参与者,例如所有合并症为 0 的参与者,我可以执行以下操作:
数据框 = allpart,列名 = CM
allpart.drop(allpart[allpart['CM'] == 0].index, inplace = True)
我怎么能改变它,让它随机选择 300k 行 w/0 合并症?我的数据框没有按该列按升序排列,因此排除了删除一大块行的可能性,我也不确定这是否足够随机。我还想提一下,我不会以此为依据得出任何合理的结论,这只是为了我自己的利益。
谢谢!
解决方案
一种解决方案是定义您希望为每种合并症保留多少行,然后groupby
+sample
选择该大小的随机子集。
我添加了一个小检查,以防您指定的行数大于该'CM'
组的 DataFrame 中存在的唯一行数。在这种情况下,它只返回所有行。
import pandas as pd
import numpy as np
np.random.seed(410112)
df = pd.DataFrame({'id': range(20), 'CM': np.random.choice([0,1,2,3,4], 20)})
# Keys is comorbidity index, value is # of rows to keep
d = {0: 1, 1: 3, 2: 2, 3: 20, 4: 2}
l = []
for idx, gp in df.groupby('CM'):
try:
gp = gp.sample(n=d[idx], replace=False)
# If try to subsample more people than exist, do nothing
except ValueError:
pass
l.append(gp)
df1 = pd.concat(l)
id CM
3 3 0
17 17 1
13 13 1
5 5 1
19 19 2
7 7 2
1 1 3
4 4 3
10 10 3
12 12 4
0 0 4
另一种类似但不需要重建整个 DataFrame(可能更快)的替代方法是再次指定d
要保留的行数的字典并用于sample(frac=1)
对 DataFrame 进行洗牌,然后groupby
+cumcount
保留行的随机子集。
# Keys is comorbidity index, value is # of rows to keep
d = {0: 1, 1: 3, 2: 2, 3: 20, 4: 2}
mask = df.sample(frac=1).groupby('CM', sort=False).cumcount().lt(df['CM'].map(d))
df1 = df[mask]
# Different subset of rows but still 1 row with CM0, 3 with CM1, ...
id CM
9 9 0
5 5 1
15 15 1
17 17 1
6 6 2
7 7 2
1 1 3
4 4 3
10 10 3
0 0 4
12 12 4
推荐阅读
- php - 现有 Array[] 中的“for each”PHP 循环
- php - 我如何将 otp 对象从服务器传递到下一个活动
- ag-grid - Ag Grid - React- 根据组数据状态更改分组行颜色 -
- regex - VB.Net 正则表达式替换保留一个变量号
- mfc - MFC 应用程序中的 HTML 表格数据问题
- android-layout - 如何在 Flutter 中添加 XML Google Pay 按钮
- sql-server - 从 VB.NET 中的 SQL Server 中选择过去 24 小时的数据
- reactjs - 如何过滤搜索结果?
- r - 从一行中选择某些元素并计算这些元素的平均值
- python - Python - 在 Django 管理员中添加自定义用户模型不起作用