如何在python中通过删除组中的某些行
我有一个dataframe,我想基于列执行如何在python中通过删除组中的某些行,python,group-by,pandas-groupby,Python,Group By,Pandas Groupby,我有一个dataframe,我想基于列执行groupby(),然后根据日期列对每个组中的值进行排序。然后,从a each中,我想删除列\u条件值=='B'的记录,直到我到达列\u条件=='a'的行。例如,假设下表是其中一个组 ID, DATE, column_condition -------------------------- 1, jan 2017, B 1, Feb 2017, B 1, Mar 2017, B 1, Aug 2017, A 1, Sept 2017, B 所以,我想删
groupby()
,然后根据日期列对每个组中的值进行排序。然后,从a each中,我想删除列\u条件值=='B'
的记录,直到我到达列\u条件=='a'
的行。例如,假设下表是其中一个组
ID, DATE, column_condition
--------------------------
1, jan 2017, B
1, Feb 2017, B
1, Mar 2017, B
1, Aug 2017, A
1, Sept 2017, B
所以,我想删除前三行,只剩下最后两行。我怎样才能做到这一点呢?我不确定是否有更干净的方法可以做到这一点,但我相信以下方法应该有效:
for index, row in df.iterrows():
if row["column_condition"] == "A":
break
elif row["column_condition"] == "B":
df.drop(index, inplace=True)
我不确定是否有更干净的方法可以做到这一点,但我认为以下方法应该有效:
for index, row in df.iterrows():
if row["column_condition"] == "A":
break
elif row["column_condition"] == "B":
df.drop(index, inplace=True)
我想我终于理解了您的问题:您希望通过
'ID'
对groupby
adataframe
进行排序,并将第一次出现'a'
后的行保留在条件
列中。我提出了以下一行解决方案:
设置虚拟数据
import pandas as pd
import datetime as dt
d = {
'ID': [1, 1, 1, 1, 1, 2, 2, 2, 2, 2], # Assuming only two unique IDs for simplicity
'DATE': [ # Dates already sorted, but it would work anyways
dt.date(2018, 7, 19), dt.date(2018, 8, 18),
dt.date(2018, 9, 17), dt.date(2018, 10, 17),
dt.date(2018, 11, 16), dt.date(2018, 7, 19),
dt.date(2018, 8, 18), dt.date(2018, 9, 17),
dt.date(2018, 10, 17), dt.date(2018, 11, 16)
],
'condition': ['B', 'B', 'B', 'A', 'B', 'B', 'B', 'B', 'A', 'B']
}
# 'DATE' but with list comprehension:
# [dt.date.today() + dt.timedelta(days=30*x) for y in range(0, 2) for x in range(0, 5)]
df = pd.DataFrame(d)
口译员
>>> (df.sort_values(by='DATE') # we should call pd.to_datetime() first if...
... .groupby('ID') # 'DATE' is not datetime already
... .apply(lambda x: x[(x['condition'].values == 'A').argmax():]))
ID DATE condition
ID
1 3 1 2018-10-17 A
4 1 2018-11-16 B
2 8 2 2018-10-17 A
9 2 2018-11-16 B
>>> df
ID DATE condition
0 1 2018-07-19 B
1 1 2018-08-18 B
2 1 2018-09-17 B
3 1 2018-10-17 B
4 1 2018-11-16 B
5 2 2018-07-19 B
6 2 2018-08-18 B
7 2 2018-09-17 B
8 2 2018-10-17 A
9 2 2018-11-16 B
>>> (df.sort_values(by='DATE')
... .groupby('ID')
... .filter(lambda x: (x['condition'] == 'A').any())
... .groupby('ID')
... .apply(lambda x: x[(x['condition'].values == 'A').argmax():]))
ID DATE condition
ID
2 8 2 2018-10-17 A
9 2 2018-11-16 B
如果您需要以下内容,也可以调用reset\u index(drop=True)
:
ID DATE condition
0 1 2018-10-17 A
1 1 2018-11-16 B
2 2 2018-10-17 A
3 2 2018-11-16 B
(x['condition'].values='A')
返回一个bool
np.array
,调用argmax()
为我们提供了True
第一次出现的索引(在这种情况下,condition='A'
)。使用该索引,我们使用切片对每个组进行子集划分
编辑:添加了用于处理仅包含不需要的条件的组的筛选器
d = {
'ID': [1, 1, 1, 1, 1, 2, 2, 2, 2, 2], # Assuming only two unique IDs for simplicity
'DATE': [ # Dates already sorted, but it would work anyways
dt.date(2018, 7, 19), dt.date(2018, 8, 18),
dt.date(2018, 9, 17), dt.date(2018, 10, 17),
dt.date(2018, 11, 16), dt.date(2018, 7, 19),
dt.date(2018, 8, 18), dt.date(2018, 9, 17),
dt.date(2018, 10, 17), dt.date(2018, 11, 16)
], # ID 1 only contains 'B'
'condition': ['B', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'A', 'B']
}
df = pd.DataFrame(d)
口译员
>>> (df.sort_values(by='DATE') # we should call pd.to_datetime() first if...
... .groupby('ID') # 'DATE' is not datetime already
... .apply(lambda x: x[(x['condition'].values == 'A').argmax():]))
ID DATE condition
ID
1 3 1 2018-10-17 A
4 1 2018-11-16 B
2 8 2 2018-10-17 A
9 2 2018-11-16 B
>>> df
ID DATE condition
0 1 2018-07-19 B
1 1 2018-08-18 B
2 1 2018-09-17 B
3 1 2018-10-17 B
4 1 2018-11-16 B
5 2 2018-07-19 B
6 2 2018-08-18 B
7 2 2018-09-17 B
8 2 2018-10-17 A
9 2 2018-11-16 B
>>> (df.sort_values(by='DATE')
... .groupby('ID')
... .filter(lambda x: (x['condition'] == 'A').any())
... .groupby('ID')
... .apply(lambda x: x[(x['condition'].values == 'A').argmax():]))
ID DATE condition
ID
2 8 2 2018-10-17 A
9 2 2018-11-16 B
我想我终于理解了您的问题:您希望通过'ID'
对groupby
adataframe
进行排序,并将第一次出现'a'
后的行保留在条件
列中。我提出了以下一行解决方案:
设置虚拟数据
import pandas as pd
import datetime as dt
d = {
'ID': [1, 1, 1, 1, 1, 2, 2, 2, 2, 2], # Assuming only two unique IDs for simplicity
'DATE': [ # Dates already sorted, but it would work anyways
dt.date(2018, 7, 19), dt.date(2018, 8, 18),
dt.date(2018, 9, 17), dt.date(2018, 10, 17),
dt.date(2018, 11, 16), dt.date(2018, 7, 19),
dt.date(2018, 8, 18), dt.date(2018, 9, 17),
dt.date(2018, 10, 17), dt.date(2018, 11, 16)
],
'condition': ['B', 'B', 'B', 'A', 'B', 'B', 'B', 'B', 'A', 'B']
}
# 'DATE' but with list comprehension:
# [dt.date.today() + dt.timedelta(days=30*x) for y in range(0, 2) for x in range(0, 5)]
df = pd.DataFrame(d)
口译员
>>> (df.sort_values(by='DATE') # we should call pd.to_datetime() first if...
... .groupby('ID') # 'DATE' is not datetime already
... .apply(lambda x: x[(x['condition'].values == 'A').argmax():]))
ID DATE condition
ID
1 3 1 2018-10-17 A
4 1 2018-11-16 B
2 8 2 2018-10-17 A
9 2 2018-11-16 B
>>> df
ID DATE condition
0 1 2018-07-19 B
1 1 2018-08-18 B
2 1 2018-09-17 B
3 1 2018-10-17 B
4 1 2018-11-16 B
5 2 2018-07-19 B
6 2 2018-08-18 B
7 2 2018-09-17 B
8 2 2018-10-17 A
9 2 2018-11-16 B
>>> (df.sort_values(by='DATE')
... .groupby('ID')
... .filter(lambda x: (x['condition'] == 'A').any())
... .groupby('ID')
... .apply(lambda x: x[(x['condition'].values == 'A').argmax():]))
ID DATE condition
ID
2 8 2 2018-10-17 A
9 2 2018-11-16 B
如果您需要以下内容,也可以调用reset\u index(drop=True)
:
ID DATE condition
0 1 2018-10-17 A
1 1 2018-11-16 B
2 2 2018-10-17 A
3 2 2018-11-16 B
(x['condition'].values='A')
返回一个bool
np.array
,调用argmax()
为我们提供了True
第一次出现的索引(在这种情况下,condition='A'
)。使用该索引,我们使用切片对每个组进行子集划分
编辑:添加了用于处理仅包含不需要的条件的组的筛选器
d = {
'ID': [1, 1, 1, 1, 1, 2, 2, 2, 2, 2], # Assuming only two unique IDs for simplicity
'DATE': [ # Dates already sorted, but it would work anyways
dt.date(2018, 7, 19), dt.date(2018, 8, 18),
dt.date(2018, 9, 17), dt.date(2018, 10, 17),
dt.date(2018, 11, 16), dt.date(2018, 7, 19),
dt.date(2018, 8, 18), dt.date(2018, 9, 17),
dt.date(2018, 10, 17), dt.date(2018, 11, 16)
], # ID 1 only contains 'B'
'condition': ['B', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'A', 'B']
}
df = pd.DataFrame(d)
口译员
>>> (df.sort_values(by='DATE') # we should call pd.to_datetime() first if...
... .groupby('ID') # 'DATE' is not datetime already
... .apply(lambda x: x[(x['condition'].values == 'A').argmax():]))
ID DATE condition
ID
1 3 1 2018-10-17 A
4 1 2018-11-16 B
2 8 2 2018-10-17 A
9 2 2018-11-16 B
>>> df
ID DATE condition
0 1 2018-07-19 B
1 1 2018-08-18 B
2 1 2018-09-17 B
3 1 2018-10-17 B
4 1 2018-11-16 B
5 2 2018-07-19 B
6 2 2018-08-18 B
7 2 2018-09-17 B
8 2 2018-10-17 A
9 2 2018-11-16 B
>>> (df.sort_values(by='DATE')
... .groupby('ID')
... .filter(lambda x: (x['condition'] == 'A').any())
... .groupby('ID')
... .apply(lambda x: x[(x['condition'].values == 'A').argmax():]))
ID DATE condition
ID
2 8 2 2018-10-17 A
9 2 2018-11-16 B
那么,如何将其与group by结合起来呢?你能解释一下你想从group by中得到什么吗?我正在对我的df进行group by,并希望将此逻辑应用于每个组。我上面展示的例子只是一个groupsCan,你发布了你的组的逻辑吗?不看它,我假设您可以在您拥有的组上进行迭代,并对每个组应用此过程。我在group by df.groupby('id').apply(lambda x:function(x))之后的apply()方法中使用了您的函数,但它看起来什么都不做!那么,如何将其与group by结合起来呢?你能解释一下你想从group by中得到什么吗?我正在对我的df进行group by,并希望将此逻辑应用于每个组。我上面展示的例子只是一个groupsCan,你发布了你的组的逻辑吗?不看它,我假设您可以在您拥有的组上进行迭代,并对每个组应用此过程。我在group by df.groupby('id').apply(lambda x:function(x))之后的apply()方法中使用了您的函数,但它看起来什么都不做!您使用哪一列进行分组<代码>ID
?你能举一个更完整的例子来说明你在做什么吗?Id用于分组依据和日期对每个分组进行排序。你使用什么函数来聚合分组依据结果?很难理解您来自何处。没有聚合函数。我只想分组,然后在每个分组上应用我上面解释的逻辑。您对分组使用的是哪列<代码>ID
?你能举一个更完整的例子来说明你在做什么吗?Id用于分组依据和日期对每个分组进行排序。你使用什么函数来聚合分组依据结果?很难理解您来自何处。没有聚合函数。我只想分组,然后在每个组上应用我上面解释的逻辑。我正在我的数据帧上尝试,但由于某些原因,它不起作用!没有错误,但它没有按照我想要的方式工作。我也试过使用argmin,但没有任何变化。您是否看到我的虚拟数据和您的真实数据之间有任何实质性差异?您是否在datetime
中的'DATE'
列?我发现了问题;如果一个组只包含“B”,它将返回整个组。我们如何修复它/?不,是的,从:返回沿轴的最大值的索引。如果最大值多次出现,则返回与第一次出现对应的索引。我正在我的数据帧上尝试,但由于某种原因它不起作用!没有错误,但它没有按照我想要的方式工作。我也试过使用argmin,但没有任何变化。您是否看到我的虚拟数据和您的真实数据之间有任何实质性差异?您是否在datetime
中的'DATE'
列?我发现了问题;如果一个组只包含“B”,它将返回整个组。我们如何修复它/?否,它是从:返回沿轴的最大值的索引。如果最大值多次出现,则返回与第一次出现对应的索引。