这是我正在使用的DF的虚拟示例(“ ETC”代表几列):
df = pd.DataFrame(data={'PlotCode':['A','A','A','A','B','B','B','C','C'],
'INVYR':[2000,2000,2000,2005,1990,2000,1990,2005,2001],
'ETC':['a','b','c','d','e','f','g','h','i']})
这就是我想要的最终结果:
df1 = pd.DataFrame(data={'PlotCode':['A','A','A','B','B','C'],
'INVYR':[2000,2000,2000,1990,1990,2001],
'ETC':['a','b','c','e','g','i']})
注意:我希望所有行的每个“ PlotCode”具有最小的“ INVYR”值,而不仅仅是一个,否则我假设我可以使用drop_duplicates和sort做些简单的事情。
到目前为止,按照此处的答案,在for循环中生成的追加pandas数据帧,我已经尝试使用以下代码进行此操作:
df1 = []
for i in df['PlotCode'].unique():
j = df[df['PlotCode']==i]
k = j[j['INVYR']==j['INVYR'].min()]
df1.append(k)
df1 = pd.concat(df1)
该代码有效,但速度很慢,我的实际数据包含大约40,000个不同的PlotCode,因此这不是可行的解决方案。有人知道这样做的某种平滑过滤方式吗?我觉得我缺少一些非常简单的东西。
先感谢您!
使用熊猫时,请尽量不要使用for循环,与熊猫的矢量化操作相比,它们的运行速度非常慢。
解决方案1:
使用.groupby()确定每个绘图代码的最小INVYR :
min_invyr_per_plotcode = df.groupby('PlotCode', as_index=False)['INVYR'].min()
并使用pd.merge()在原始df与您刚刚发现的最小值之间进行内部联接:
result_df = pd.merge(
df,
min_invyr_per_plotcode,
how='inner',
on=['PlotCode', 'INVYR'],
)
解决方案2:
同样,确定每组的最小值,但现在将其作为一列添加到数据框。每组的最小值通过使用.groupby()。transform()添加到每一行
df['min_per_group'] = (df
.groupby('PlotCode')['INVYR']
.transform('min')
)
现在,过滤您的数据框,其中连续INVYR等于该组的最小值:
df[df['INVYR'] == df['min_per_group']]
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句