可以对熊猫GroupBy对象执行group_by操作吗?

时间:2020-05-14 11:03:24

标签: python pandas group-by

我需要对一个大熊猫数据框执行非常昂贵的分组操作,并想知道是否有可能先对数据框的前n列进行分组,然后根据我的代码中的条件,重新执行将结果对象分组到另一列上,并因此将新列添加到结果对象的索引中。

当前,DataFrame如下所示:

compound_data = {
    'n1': {0: 'n1_value_1', 1: 'n1_value_2', 2: 'n1_value_3'},
    'n2': {0: 'n2_value_1', 1: 'n2_value_2', 2: 'n2_value_3'},
    'n3': {0: 'n3_value_1', 1: 'n3_value_2', 2: 'n3_value_3'},
    'n4': {0: 'n4_value_1', 1: 'n4_value_2', 2: 'n4_value_3'},
}
compound_data_frame = pd.DataFrame(compound_data)

调用groupby的代码块如下所示:

categorical_columns = ['n3', 'n4']

for column in categorical_columns:
    counts = compound_data_frame.groupby(
                ['n1', 'n2', column]).size()

这意味着我最终将n1和n2分组了两次,我担心执行时间会不必要地花费很多。我只想按n1和n2分组一次,然后以某种方式按n3分组第一次分组的结果,然后对n4重复此过程。

因此,如果我要首先对“ n1”和“ n2”列进行分组,则生成的对象可能看起来像这样(我们将此对象称为“ first_grouping”):

                      n3
index 
n1_value/n2_value    n3_value

我希望以后可以将其按n3分组并计算结果,以得出以下结果:

                                count
index 
n1_value/n2_value/n3_value      1

之后,我要获取first_grouping对象,但是这次我要按n4而不是n3进行分组,以便最终结果如下所示:

                                count
index 
n1_value/n2_value/n4_value      1

我需要能够访问包含该对象已分组到的所有列的索引,因为这些计数用于更新另一个包含这些操作结果的数据框。第二个数据帧具有如下所示的多重索引:

                            count
index 
n1_value/n2_value/n3_value      1 
n1_value/n2_value/n4_value      1

将原始实现与新的,全面的groupby操作一起使用太慢了。

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

IIUC,是的,您可以嵌套groupby,因为在下面的示例中,apply中的变量x是一个数据帧,因此您可以执行相同的操作(例如{ {1}}),就像在任何数据帧上一样:

groupby

尽管在这种情况下,简单的df_ = pd.DataFrame({'n1':list('a'*8), 'n2':list('b'*4+'c'*4), 'n3':list('d'*2+'e'*2)*2, 0:range(8)}) print (df_.groupby(['n1','n2']).apply(lambda x: x.groupby('n3')[[0]].count())) 0 n1 n2 n3 a b d 2 e 2 c d 2 e 2 也会这样做。

编辑:一个更好的示例,该函数根据分组数据帧的大小执行不同的操作:

df_.groupby(['n1','n2','n3'])[[0]].count()

EDIT2:关于问题中的新信息,我认为您可以尝试对n1和n2仅执行def f(x): gr = x.groupby('n3')[[0]] return gr.count() if len(x)>=4 else gr.tail(1) df_ = pd.DataFrame({'n1':list('a'*8), 'n2':list('b'*6+'c'*2), 'n3':list('d'*7+'e'), 0:range(8)}) print (df_.groupby(['n1','n2']).apply(f)) 0 n1 n2 n3 a b d 6 #returned the count c 6 6 #returned the last value of the group 7 7 #... ,然后对categorical_columns的列执行groupbyvalue_counts的结果如下:

concat