3 回答

TA贡献1812条经验 获得超5个赞
解决方案出奇地短:
df.groupby('inn_main').apply(lambda grp:
grp[~grp.Help.isin(years).cumsum().shift(fill_value=0).astype(bool)])
结果是:
inn_main Help
inn_main
Apple 0 Apple OK
1 Apple OK
2 Apple 2013
Tesla 4 Tesla OK
5 Tesla 2014
详:
df.groupby('inn_main')
- 按公司对数据帧进行分组。apply(lambda grp:
- 将 lambda 函数应用于每个组。grp.Help.isin(years)
- 帮助是否以年为单位有价值?.cumsum()
- 上述问题的累计总和。shift(fill_value=0)
- 将结果向下移动1行,用0填充任何NaN(实际上是第一项)。astype(bool)
- 将整数转换为布尔。~
- 否定上述结果[...]
- 在布尔索引中使用上述结果。grp[...]
- 从当前组返回“好”行(它们将是当前组的结果的一部分)。
注意:ASGM 的解决方案仅删除第一行,在包含“帮助”的任何行之后,第一行“确定”。
要确认这一点,请将另一行包含 Tesla 和 OK 添加到 DataFrame 并运行他的代码。
结果是:
inn_main Help
0 Apple OK
1 Apple OK
2 Apple 2013
4 Tesla OK
5 Tesla 2014
7 Tesla OK
因此,索引 == 7(应删除)的行存在。

TA贡献1817条经验 获得超6个赞
我不完全理解你的要求,但这就是我认为你想要的。给定以下数据帧...
Help inn_main
0 OK Apple
1 OK Apple
2 2013 Apple
3 OK Apple
4 OK Tesla
5 2014 Tesla
6 OK Tesla
...您希望标识 列表中的每一行,并删除其后面的行(在属于给定公司的行中)。如果这是正确的,你可以做得更简单:df.Helpyears
years = range(2012, 2019)
df[~df.groupby('inn_main')['Help'].apply(lambda g: g.isin(years).shift().fillna(False))]
这将提供:
Help inn_main
0 OK Apple
1 OK Apple
2 2013 Apple
4 OK Tesla
5 2014 Tesla
如果要删除公司内给定行后面的所有行,Valdi_Bo的完整答案将显示如何操作。

TA贡献1995条经验 获得超2个赞
我不太了解panda,也不知道你想做什么,但这里是重构的代码,用于迭代列表而不是使用索引:
import pandas as pd
data = {'inn_main':['Apple', 'Apple', 'Apple', 'Apple', 'Tesla', 'Tesla', 'Tesla'], 'Help':['OK', 'OK', 2013, 'OK','OK', 2014, 'OK']}
df = pd.DataFrame(data)
droper=[]
years=[2012,2013,2014,2015,2016,2017,2018]
for j in list(df['Help'].groupby(df['inn_main'])):
alarm=False
for i in j[1].index.values:
if j[1][i.astype(int)] in years:
alarm=True
elif alarm:
droper.append(i.astype(int))
df.drop(index=droper)
添加回答
举报