ombk
ombk

Reputation: 2111

Groupby into list for non consecutive values

I am trying to group by this dataset

    col1    col2
0   A   1
1   B   1
2   C   1
3   D   3
4   E   3
5   F   2
6   G   2
7   H   1
8   I   1
9   j   2
10  K   2

into this

1 : [A, B, C]
3: [D, E]
2: [ F; G]
1: [ H, I]
2: [ J,K]

so it has to capture the difference in appearances of the elements and not group all at once.

So far I was able to do the normal groupby, df.groupby("col2")["col1"].apply(list) but it isn't correct.

Upvotes: 2

Views: 676

Answers (2)

Pygirl
Pygirl

Reputation: 13349

Since Jezrael already answered is using pandas. I would like to add non pandas method.

I know this is not an efficient method but for learning purpose I included.

Using itertools's groupby

from itertools import groupby
last_index = 0
for v, g in groupby(enumerate(df.col2), lambda k: k[1]):
    l = [*g]
    print(df.iloc[last_index]['col2'],':', df.iloc[last_index:l[-1][0]+1]['col1'].values)
    last_index += len(l)

1 : ['A' 'B' 'C']
3 : ['D' 'E']
2 : ['F' 'G']
1 : ['H' 'I']
2 : ['j' 'K']

Upvotes: 1

jezrael
jezrael

Reputation: 862911

You need distinguish consecutive values by compare shifted values foe not equal with cumulative sum, last remove second level of MultiIndex:

s = (df.groupby(["col2", df["col2"].ne(df["col2"].shift()).cumsum()])["col1"]
       .agg(list)
       .reset_index(level=1, drop=True))

Upvotes: 4

Related Questions