根据GropuBy属性删除Pandas DataFrame行

时间:2017-12-05 15:25:47

标签: python pandas dataframe

我有一些DataFrames,其中包含有关某些元素的信息,例如:

my_df1=pd.DataFrame([[1,12],[1,15],[1,3],[1,6],[2,8],[2,1],[2,17]],columns=['Group','Value'])
my_df2=pd.DataFrame([[1,5],[1,7],[1,23],[2,6],[2,4]],columns=['Group','Value'])

我使用了像dfGroups = df.groupby('group').apply(my_agg).reset_index()这样的东西,所以现在我有DataFrmaes包含前面元素组的信息,比如说

my_df1_Group=pd.DataFrame([[1,57],[2,63]],columns=['Group','Group_Value'])
my_df2_Group=pd.DataFrame([[1,38],[2,49]],columns=['Group','Group_Value'])

现在我想根据元素的属性清理我的组。假设我想丢弃包含Value大于16的元素的组。因此,在my_df1_Group中,应该只剩下第一个组,而两个组都有资格留在my_df2_Group

由于我不知道如何从Python中的my_df1_Groupmy_df2_Group获取my_df1my_df2(我知道其他语言只会{{1}在name+"_Group"中使用name循环,但是如何在Python中执行此操作?),我构建了一个列表列表:

[my_df1,my_df2]

然后,我只是试试这个:

SampleList = [[my_df1,my_df1_Group],[my_df2,my_df2_Group]]

哪个运行没有错误,但不起作用。特别是,这不会将列my_max=16 Bad=[] for Sample in SampleList: for n in Sample[1]['Group']: df=Sample[0].loc[Sample[0]['Group']==n] #This is inelegant, but trying to work #with Sample[1] in the for doesn't work if (df['Value'].max()>my_max): Bad.append(1) else: Bad.append(0) Sample[1] = Sample[1].assign(Bad_Row=pd.Series(Bad)) Sample[1] = Sample[1].query('Bad_Row == 0') 添加到我的df中,也不会修改我的DataFrame(但即使Bad_Row列似乎不存在,查询也会顺利运行...)。另一方面,如果我在df上手动运行这种技术(即不在循环中),它就可以工作。

我该怎么办?

2 个答案:

答案 0 :(得分:1)

根据您在下面的评论,我认为您想要检查汇总数据框中的Group输入数据中的Value是否大于16.一个解决方案是执行一行使用输入数据的标准进行计算。为此,my_func从聚合数据框接受一行,并将输入数据作为pandas groupby对象接受。对于分组数据框中的每个组,它将对您的初始数据进行子集化,并使用布尔逻辑来查看输入数据中的任何“值”是否符合您指定的标准。

def my_func(row,grouped_df1):
    if (grouped_df1.get_group(row['Group'])['Value']>16).any():
        return 'Bad Row'
    else:
        return 'Good Row'

my_df1=pd.DataFrame([[1,12],[1,15],[1,3],[1,6],[2,8],[2,1],[2,17]],columns=['Group','Value'])

my_df1_Group=pd.DataFrame([[1,57],[2,63]],columns=['Group','Group_Value'])

grouped_df1 = my_df1.groupby('Group')

my_df1_Group['Bad_Row'] = my_df1_Group.apply(lambda x: my_func(x,grouped_df1), axis=1)

返回:

   Group  Group_Value   Bad_Row
0      1           57  Good Row
1      2           63   Bad Row

答案 1 :(得分:0)

基于dubbbdan的想法,有一个有效的代码:

my_max=16
def my_func(row,grouped_df1):
    if (grouped_df1.get_group(row['Group'])['Value']>my_max).any():
        return 1
    else:
        return 0

SampleList = [[my_df1,my_df1_Group],[my_df2,my_df2_Group]]


for Sample in SampleList:
    grouped_df = Sample[0].groupby('Group')
    Sample[1]['Bad_Row'] = Sample[1].apply(lambda x: my_func(x,grouped_df), axis=1)                     
    Sample[1].drop(Sample[1][Sample[1]['Bad_Row']!=0].index, inplace=True)
    Sample[1].drop(['Bad_Row'], axis = 1, inplace = True)