Pandas DataFrame: 删除符合列条件的行

3

我有一个很大的面板数据存储在pandas DataFrame中:data

import pandas as pd 

df = pd.read_csv('Qs_example_data.csv')

df.head()

ID      Year    DOB  status YOD
223725  1991    1975.0  No  2021
223725  1992    1975.0  No  2021
223725  1993    1975.0  No  2021
223725  1994    1975.0  No  2021
223725  1995    1975.0  No  2021



我想根据以下条件删除行: 如果在 YOD 中的值与 Year 中的值匹配,则删除该 ID 的匹配行后的所有行;或者如果在该 IDstatus 列中观察到一个 Yes,则删除该 ID 的所有行。
例如,在 DataFrame 中,ID 68084329 在第 221930 行具有 DOBYOD 列中的 2012 值。应删除 68084329 的 221930 之后的所有行。
df.loc[x['ID'] == 68084329]

          ID        Year     DOB  status YOD
221910  68084329    1991    1942.0  No  2012
221911  68084329    1992    1942.0  No  2012
221912  68084329    1993    1942.0  No  2012
221913  68084329    1994    1942.0  No  2012
221914  68084329    1995    1942.0  No  2012
221915  68084329    1996    1942.0  No  2012
221916  68084329    1997    1942.0  No  2012
221917  68084329    1998    1942.0  No  2012
221918  68084329    1999    1942.0  No  2012
221919  68084329    2000    1942.0  No  2012
221920  68084329    2001    1942.0  No  2012
221921  68084329    2002    1942.0  No  2012
221922  68084329    2003    1942.0  No  2012
221923  68084329    2004    1942.0  No  2012
221924  68084329    2005    1942.0  No  2012
221925  68084329    2006    1942.0  No  2012
221926  68084329    2007    1942.0  No  2012
221927  68084329    2008    1942.0  No  2012
221928  68084329    2010    1942.0  No  2012
221929  68084329    2011    1942.0  No  2012
221930  68084329    2012    1942.0  Yes 2012
221931  68084329    2013    1942.0  No  2012
221932  68084329    2014    1942.0  No  2012
221933  68084329    2015    1942.0  No  2012
221934  68084329    2016    1942.0  No  2012
221935  68084329    2017    1942.0  No  2012

我有很多ID,这些ID的行需要根据上述条件删除。我该怎么做?


7
你的数据似乎是按'年份'排序的,因此是否可以只删除'年份'> YOD 的行? (至少对于你的第一个条件) - Adept
1
是的,它完美地工作了,谢谢你的帮助。我使用了 x = df[df["Year"] > df["YOD"]].index 然后 df.drop(x, inplace = True) - MI MA
还是只用 df[df["Year"] <= df["YOD"]] - Henry Yik
2个回答

1
以下代码也应该可行:

result=df[0:0]
ids=[]
for i in df.ID:
    if i not in ids:
        ids.append(i)

for k in ids:
  temp=df[df.ID==k]
  for j in range(len(temp)):
    result=pd.concat([result, temp.iloc[j:j+1, :]])
    if temp.iloc[j, :]['status']=='Yes':
      break

print(result)

1
这样做应该可以。从您的措辞中,不清楚您是否需要“在遇到该ID的Yes之后删除所有行”,还是“仅删除您遇到的Yes所在的行”。我假设您需要“在遇到该ID的Yes之后删除所有行”。
import pandas as pd


def __get_nos__(df):
    return df.iloc[0:(df['Status'] != 'Yes').values.argmin(), :]


df = pd.DataFrame()
df['ID'] = [12345678]*10 + [13579]*10
df['Year'] = list(range(2000, 2010))*2
df['DOB'] = list(range(2000, 2010))*2
df['YOD'] = list(range(2000, 2010))*2
df['Status'] = ['No']*5 + ['Yes']*5 + ['No']*7 + ['Yes']*3
""" df
          ID  Year   DOB   YOD Status
0   12345678  2000  2000  2000     No
1   12345678  2001  2001  2001     No
2   12345678  2002  2002  2002     No
3   12345678  2003  2003  2003     No
4   12345678  2004  2004  2004     No
5   12345678  2005  2005  2005    Yes
6   12345678  2006  2006  2006    Yes
7   12345678  2007  2007  2007    Yes
8   12345678  2008  2008  2008    Yes
9   12345678  2009  2009  2009    Yes
10     13579  2000  2000  2000     No
11     13579  2001  2001  2001     No
12     13579  2002  2002  2002     No
13     13579  2003  2003  2003     No
14     13579  2004  2004  2004     No
15     13579  2005  2005  2005     No
16     13579  2006  2006  2006     No
17     13579  2007  2007  2007    Yes
18     13579  2008  2008  2008    Yes
19     13579  2009  2009  2009    Yes
"""
df.groupby('ID').apply(lambda x: __get_nos__(x)).reset_index(drop=True)
""" Output
          ID  Year   DOB   YOD Status
0      13579  2000  2000  2000     No
1      13579  2001  2001  2001     No
2      13579  2002  2002  2002     No
3      13579  2003  2003  2003     No
4      13579  2004  2004  2004     No
5      13579  2005  2005  2005     No
6      13579  2006  2006  2006     No
7   12345678  2000  2000  2000     No
8   12345678  2001  2001  2001     No
9   12345678  2002  2002  2002     No
10  12345678  2003  2003  2003     No
11  12345678  2004  2004  2004     No
"""

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接