Using slice on DaraFrameGroupBy

Viewed 31

I need to use slice on DataFrameGroupBy object.

For example, assume there is DataFrame with A-Z columns, if I want to use columns A-C I will use .loc[:, 'A':'C'], but when I'm using DataFrameGroupBy, I can't use slicing so I have to write [['A', 'B', 'C']]

Take a look here:

from numpy import around
from numpy.random import uniform
from pandas import DataFrame
from string import ascii_lowercase

data = around(a=uniform(low=1.0, high=50.0, size=(6, len(ascii_lowercase) + 1)), decimals=3)
df = DataFrame(data=data, columns=['group'] + list(ascii_lowercase), dtype='float64')

rows, columns = df.shape
df.loc[:rows // 2, 'group'] = 1.0
df.loc[rows // 2:, 'group'] = 2.0

print(df)
abc = df.groupby(by='group')[['a', 'b', 'c']].shift(periods=1)
print(abc)

Output of df is:

   group       a       b       c  ...       w       x       y       z
0    1.0  22.380  36.873  10.073  ...  26.052  38.625  48.122  33.841
1    1.0  16.702  32.160  35.018  ...  12.990  17.878  19.297  16.330
2    1.0   9.957  25.202   7.106  ...  46.500  12.932  37.401  43.134
3    2.0  42.395  40.616  24.611  ...  30.436  33.521  42.136   2.690
4    2.0   2.069  29.891   2.217  ...  20.734  12.365   9.302  47.019
5    2.0   4.208  23.955  33.966  ...  45.439  16.488  32.892   9.345

Output of abc is:

        a       b       c
0     NaN     NaN     NaN
1  22.380  36.873  10.073
2  16.702  32.160  35.018
3     NaN     NaN     NaN
4  42.395  40.616  24.611
5   2.069  29.891   2.217

How can I avoid of using [['a', 'b', 'c']]? I have 105 columns that I need to write there, I want use slicing like .loc[:, 'a':'c']

Thank you all :)

1 Answers

You can grouping by Series df['group'], so is possible filter columns before groupby to pass only filtered columns names:

abc = df.loc[:, 'a':'c'].groupby(by=df['group']).shift(periods=1)
print(abc)
        a       b       c
0     NaN     NaN     NaN
1  37.999  21.197  39.527
2  35.560  27.214  23.211
3     NaN     NaN     NaN
4  49.053  11.319  37.279
5  27.881  38.529  46.550

Another idea is use:

cols = df.loc[:, 'a':'c'].columns
abc = df.groupby(by='group')[cols].shift(periods=1)
Related