Pandas:如果组中的最后一个值满足要求的条件,则从数据框中删除组
Pandas: remove group from dataframe if the last value in the group meets a required condition
找到了类似的问题 ,但我无法解决一个小问题,而且我不断遇到错误。代码是否有可能查看组中的最后一项,并根据条件是否存在,它会删除整个组?
条件是:如果最后一行的 'Status' 在 30 到 39 之间(含),则丢弃整个组。
我使用了与上述 link 中类似的方法,使用 apply() 和 filter()。
当我使用 apply 方法时,此代码仅删除具有该条件的行而不是完整的组:
df.groupby('Sort_Key').apply(lambda x: x[~x['Status'].between(30,39,inclusive=True)])
但是当我按照上面 link 中的建议使用过滤方法时,我得到一个错误
df.groupby('Sort_Key').filter(lambda x: x[~x['Status'].between(30,39,inclusive=True)])
TypeError: filter function returned a Series, but expected a scalar bool
所以第一,我的过滤方法有什么问题?这是解决此问题的最佳方法吗?
第二。有没有办法将条件基于该系列的最后一行。
数据集:
df = pd.DataFrame({'Sort_Key': ['100000003', '100000009', '100000009', '100000009', '100000034','100000034', '100000034', '100000048'],
'Claim_no': [40000, 50000, 42000, 50000, 42000, 50000, 42000, 5000],
'Discharge': [456435, 50345345, 4345435,345756,34557,6867456,345435,346546],
'Admit': [678678, 67867867, 678678,678679,8989,67867,89697,9678678],
'Status': [12, 12, 52,30,30,18,19,30]})
原始数据框:
Admit Claim_no Discharge Sort_Key Status
Sort_Key
100000003 0 678678 40000 456435 100000003 12
100000009 1 67867867 50000 50345345 100000009 12
2 678678 42000 4345435 100000009 52
3 678679 50000 345756 100000009 30
100000034 4 8989 42000 34557 100000034 30
5 67867 50000 6867456 100000034 18
6 89697 42000 345435 100000034 19
100000048 7 9678678 5000 346546 100000048 30
最终数据帧:
Admit Claim_no Discharge Sort_Key Status
Sort_Key
100000003 0 678678 40000 456435 100000003 12
100000034 4 8989 42000 34557 100000034 30
5 67867 50000 6867456 100000034 18
6 89697 42000 345435 100000034 19
修复您的代码
df.groupby('Sort_Key').filter(lambda x: ~pd.Series(x['Status'].iloc[-1]).between(30,39,inclusive=True).any())
Out[325]:
Admit Claim_no Discharge Sort_Key Status
0 678678 40000 456435 100000003 12
4 8989 42000 34557 100000034 30
5 67867 50000 6867456 100000034 18
6 89697 42000 345435 100000034 19
我会做什么
s=df.groupby('Sort_Key').Status.last()
df.loc[~df.Sort_Key.isin(s[s!=30].index)]
Out[333]:
Admit Claim_no Discharge Sort_Key Status
1 67867867 50000 50345345 100000009 12
2 678678 42000 4345435 100000009 52
3 678679 50000 345756 100000009 30
7 9678678 5000 346546 100000048 30
我会这样做:
In [25]: df[df.groupby('Sort_Key')['Status']
.transform(lambda x: not x.tail(1).between(30,39).any())]
Out[25]:
Admit Claim_no Discharge Sort_Key Status
0 678678 40000 456435 100000003 12
4 8989 42000 34557 100000034 30
5 67867 50000 6867456 100000034 18
6 89697 42000 345435 100000034 19
找到了类似的问题
我使用了与上述 link 中类似的方法,使用 apply() 和 filter()。 当我使用 apply 方法时,此代码仅删除具有该条件的行而不是完整的组:
df.groupby('Sort_Key').apply(lambda x: x[~x['Status'].between(30,39,inclusive=True)])
但是当我按照上面 link 中的建议使用过滤方法时,我得到一个错误
df.groupby('Sort_Key').filter(lambda x: x[~x['Status'].between(30,39,inclusive=True)])
TypeError: filter function returned a Series, but expected a scalar bool
所以第一,我的过滤方法有什么问题?这是解决此问题的最佳方法吗?
第二。有没有办法将条件基于该系列的最后一行。
数据集:
df = pd.DataFrame({'Sort_Key': ['100000003', '100000009', '100000009', '100000009', '100000034','100000034', '100000034', '100000048'],
'Claim_no': [40000, 50000, 42000, 50000, 42000, 50000, 42000, 5000],
'Discharge': [456435, 50345345, 4345435,345756,34557,6867456,345435,346546],
'Admit': [678678, 67867867, 678678,678679,8989,67867,89697,9678678],
'Status': [12, 12, 52,30,30,18,19,30]})
原始数据框:
Admit Claim_no Discharge Sort_Key Status
Sort_Key
100000003 0 678678 40000 456435 100000003 12
100000009 1 67867867 50000 50345345 100000009 12
2 678678 42000 4345435 100000009 52
3 678679 50000 345756 100000009 30
100000034 4 8989 42000 34557 100000034 30
5 67867 50000 6867456 100000034 18
6 89697 42000 345435 100000034 19
100000048 7 9678678 5000 346546 100000048 30
最终数据帧:
Admit Claim_no Discharge Sort_Key Status
Sort_Key
100000003 0 678678 40000 456435 100000003 12
100000034 4 8989 42000 34557 100000034 30
5 67867 50000 6867456 100000034 18
6 89697 42000 345435 100000034 19
修复您的代码
df.groupby('Sort_Key').filter(lambda x: ~pd.Series(x['Status'].iloc[-1]).between(30,39,inclusive=True).any())
Out[325]:
Admit Claim_no Discharge Sort_Key Status
0 678678 40000 456435 100000003 12
4 8989 42000 34557 100000034 30
5 67867 50000 6867456 100000034 18
6 89697 42000 345435 100000034 19
我会做什么
s=df.groupby('Sort_Key').Status.last()
df.loc[~df.Sort_Key.isin(s[s!=30].index)]
Out[333]:
Admit Claim_no Discharge Sort_Key Status
1 67867867 50000 50345345 100000009 12
2 678678 42000 4345435 100000009 52
3 678679 50000 345756 100000009 30
7 9678678 5000 346546 100000048 30
我会这样做:
In [25]: df[df.groupby('Sort_Key')['Status']
.transform(lambda x: not x.tail(1).between(30,39).any())]
Out[25]:
Admit Claim_no Discharge Sort_Key Status
0 678678 40000 456435 100000003 12
4 8989 42000 34557 100000034 30
5 67867 50000 6867456 100000034 18
6 89697 42000 345435 100000034 19