Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在python中通过删除组中的某些行_Python_Group By_Pandas Groupby - Fatal编程技术网

如何在python中通过删除组中的某些行

如何在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 所以,我想删

我有一个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

所以,我想删除前三行,只剩下最后两行。我怎样才能做到这一点呢?

我不确定是否有更干净的方法可以做到这一点,但我相信以下方法应该有效:

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
a
dataframe
进行排序,并将第一次出现
'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
a
dataframe
进行排序,并将第一次出现
'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”,它将返回整个组。我们如何修复它/?否,它是从:返回沿轴的最大值的索引。如果最大值多次出现,则返回与第一次出现对应的索引。