как агрегировать только числовые столбцы в кадре данных смешанного типа dtypes

У меня смешанный pd.DataFrame:

import pandas as pd
import numpy as np
df = pd.DataFrame({ 'A' : 1.,
                     'B' : pd.Timestamp('20130102'),
                     'C' : pd.Timestamp('20180101'),
                     'D' : np.random.rand(10),
                     'F' : 'foo' })

df
Out[12]: 
     A          B          C         D    F
0  1.0 2013-01-02 2018-01-01  0.592533  foo
1  1.0 2013-01-02 2018-01-01  0.819248  foo
2  1.0 2013-01-02 2018-01-01  0.298035  foo
3  1.0 2013-01-02 2018-01-01  0.330128  foo
4  1.0 2013-01-02 2018-01-01  0.371705  foo
5  1.0 2013-01-02 2018-01-01  0.541246  foo
6  1.0 2013-01-02 2018-01-01  0.976108  foo
7  1.0 2013-01-02 2018-01-01  0.423069  foo
8  1.0 2013-01-02 2018-01-01  0.863764  foo
9  1.0 2013-01-02 2018-01-01  0.037085  foo

Я хотел бы агрегировать свои числовые столбцы, но сохранить и нечисловые. Если я сделаю gropuby, а затем agg. Я получил:

df.groupby('B').agg(np.median)
Out[13]: 
              A         D
B                        
2013-01-02  1.0  0.482157

это нормально, и я знаю, что это желаемое поведение, поскольку другие dtypes, вероятно, вызывают исключения во время np.median, но я хотел бы также получить свой исходный столбец F со значением foo, а также C с 2018-01-01

До сих пор я решил использовать пользовательскую оболочку для своих функций числового агрегирования, например. если бы я хотел сделать nanmean по моему кадру данных:

def my_nan_median(x):
    if isinstance(x.values[0], np.datetime64):
        return np.min(x) # let the first datetime pass! 
    elif isinstance(x.values[0], str):
        return x.values[0] # let the strings pass!
    else:
        return np.nanmedian(x) 

но выглядит ужасно. Как правильно это сделать?


person 00__00__00    schedule 16.10.2017    source источник
comment
Как насчет группировки по всем столбцам? df.groupby(['B', 'C', 'F']).agg(np.median).reset_index()   -  person Jan Zeiseweis    schedule 16.10.2017
comment
Возможный дубликат отсутствующего столбца после группы pandas   -  person Brad Solomon    schedule 16.10.2017


Ответы (2)


Используя select_dtypes:

df.groupby(list(df.select_dtypes(exclude=[np.number]))).agg(np.median).reset_index()

Или что-то вроде этого:

df1 = df.groupby('B',as_index=False).agg(np.median)
pd.concat([df1,df.drop_duplicates(['B']).drop(list(df1),1).reset_index(drop=True)],axis=1)
person BENY    schedule 16.10.2017

Если «C», «F» одинаковы для каждого значения «B», вы можете включить его в столбцы groupby, например:

df.groupby(['B','C','F']).agg(np.median).reset_index()

Или, как предлагает @BradSolomn:

df.groupby(['B','C','F'], as_index=False).agg(np.median)

Выход:

           B          C    F    A         D
0 2013-01-02 2018-01-01  foo  1.0  0.392723

Если нет, то вам нужно как-то агрегировать «C», «F», например, получить первое значение из «C», «F»

df.groupby('B').agg({'D':np.median,'A':np.median,'C':'first','F':'last'}).reset_index() 

           B          C    F    A         D
0 2013-01-02 2018-01-01  foo  1.0  0.392723
person Scott Boston    schedule 16.10.2017