对dataframe进行groupby之后得到的是一个groupby对象,不能直接打印输出,但可以对这个对象进行各种计算

df = pd.DataFrame({'key1':['a','a','b','b','a'],
                   'key2':['one','two','one','two','one'],
                   'data1':np.random.randn(5),
                   'data2':np.random.randn(5)})
df

groupby python 两个 python groupby 两个变量_groupby

 1.1 根据A列的标签取值,分组计算B列的均值、和、方差、标准差等

df['data1'].groupby(df['key1']).mean()

# 其中
df['data1'].groupby(df['key1'])
# 等价于
df.groupby(df['key1'])['data1']

groupby python 两个 python groupby 两个变量_groupby python 两个_02

1.1.1 需要区分以下两种用法,踩过坑。。。 

1.1.1-1 如果传入的是series或者是1维的ndarray,一般不会出现什么错

df['data1'].groupby([df['key1'], df['key2']]).mean()

groupby python 两个 python groupby 两个变量_字符串_03

 1.1.1-2 如果传入的是字符串列表,列表的取值必须是df的字段名,就是说'key1', 'key2'必须在.groupby之前这个dataframe中

df.groupby(['key1', 'key2']).mean()

groupby python 两个 python groupby 两个变量_字符串_04

1.2 size方法

返回一个包含组大小信息的Series

df.groupby(['key1', 'key2']).size()

groupby python 两个 python groupby 两个变量_python_05

1.3 支持迭代遍历

groupby对象支持遍历,生成一个组名和数据块组成的元组(组名,数据块),有点类似于enumerate,单层组名为字符串,如果组名有多层的形式,组名将会以元组的形式展示。

for name,group in df.groupby(['key1', 'key2']):
    print(name)
    print(group, end='\n\n')

groupby python 两个 python groupby 两个变量_pandas_06

1.4 按照dataframe字段的数据类型对数据进行分块

 groupby 的axis参数默认为axis=0,也可以设置为任意轴,设为1就是对列进行操作

如按照数据类型对数据进行分块

for name,group in df.groupby(df.dtypes, axis=1):
    print(name)
    print(group, end='\n\n')

groupby python 两个 python groupby 两个变量_python_07

1.5 使用字典或Serise进行分组

people = pd.DataFrame(np.random.randn(5,5),
                  columns = ['a','b','c','d','e'],
                  index = ['joe','steve','wes','jim','travis'])
# 把一些值设为空值
people.iloc[2:3, [1,2]] = np.nan
people

groupby python 两个 python groupby 两个变量_pandas_08

1.5-1 以字典作为分组规则

mapping = {'a':'red', 'b':'red', 'c':'blue',
           'd':'blue', 'e':'red', 'f':'orange'}
by_column = people.groupby(mapping, axis=1).sum()
by_column

 

groupby python 两个 python groupby 两个变量_python_09

1.5-2 以Series作为分组规则

map_series = pd.Series(mapping)
map_series

groupby python 两个 python groupby 两个变量_python_10

people.groupby(mapping, axis=1).count()

groupby python 两个 python groupby 两个变量_groupby python 两个_11

1.6 使用函数进行分组

people.groupby(len, axis=1).count()
Out[67]: 
        1
joe     5
steve   5
wes     3
jim     5
travis  5

people.groupby(len, axis=0).count()
Out[68]: 
   a  b  c  d  e
3  3  2  2  3  3
5  1  1  1  1  1
6  1  1  1  1  1

1.7 使用索引层级进行分组

columns = pd.MultiIndex.from_arrays([['us','us','us','jp','jp'],
                                     [1,3,5,1,3]],
                                    names=['city', 'tenor'])

hier_df = pd.DataFrame(np.random.randn(4,5), columns=columns)
hier_df

groupby python 两个 python groupby 两个变量_groupby python 两个_12

hier_df.groupby(level='city', axis=1).count()

groupby python 两个 python groupby 两个变量_pandas_13

 groupby对象常用方法

groupby python 两个 python groupby 两个变量_groupby_14

groupby高阶应用

groupby.apply()  和 groupby.agg()

先分组然后对每个单独的组进行apply函数的操作,然后尝试将每一块拼接到一起

groupby python 两个 python groupby 两个变量_python_15

df = pd.DataFrame({'Q':['LI','ZHANG','ZHANG','LI','WANG'], 
                   'A' : [1,1,1,2,2], 
                   'B' : [1,-1,0,1,2], 
                   'C' : [3,4,5,6,7]})

groupby python 两个 python groupby 两个变量_字符串_16

df.groupby('Q').apply(lambda x: print(x, end='\n\n'))

groupby python 两个 python groupby 两个变量_groupby_17

df.groupby('Q').agg(lambda x: print(x, end='\n\n'))

out:
0    1
3    2
Name: A, dtype: int64

4    2
Name: A, dtype: int64

1    1
2    1
Name: A, dtype: int64

0    1
3    1
Name: B, dtype: int64

4    2
Name: B, dtype: int64

1   -1
2    0
Name: B, dtype: int64

0    3
3    6
Name: C, dtype: int64

4    7
Name: C, dtype: int64

1    4
2    5
Name: C, dtype: int64

可以看出,使用apply()处理的对象是一个个的类如DataFrame的数据表,然而agg()则每次只传入一列。

有趣的是,agg()可以同时传入多个函数:

df.groupby('Q').agg(['mean','std','count','max'])

groupby python 两个 python groupby 两个变量_pandas_18

df.groupby('Q').agg(['mean','std','count','max']).plot(kind='bar')

groupby python 两个 python groupby 两个变量_python_19

df.groupby('Q').apply(np.mean)

groupby python 两个 python groupby 两个变量_python_20

在使用apply的过程中,如果还需要传递其他参数或关键字的话,可以把这些放在函数后进行传递

groupby python 两个 python groupby 两个变量_groupby python 两个_21

transform方法

.transform 可以产生一个标量值,并广播到各分组的尺寸数据中

.transform 可以产生一个与输入尺寸相同的对象

.transform 不可以改变它的输入

df = pd.DataFrame({'key': ['a', 'b', 'c'] * 4,
                   'value': np.arange(12)})
df

groupby python 两个 python groupby 两个变量_python_22

df.groupby('key').value.mean()

groupby python 两个 python groupby 两个变量_字符串_23

如果想要产生一个Series,它的尺寸和df['value']一样,但值都被‘key’分组后计算的值替代。可以向transform传递一个匿名函数

df.groupby('key').transform(lambda x: x.mean()) # 替换成均值

groupby python 两个 python groupby 两个变量_groupby_24

如果传递的函数是python的内建函数,可以像groupby中的agg方法一样传递一个字符串别名:

groupby python 两个 python groupby 两个变量_groupby python 两个_25

与apply相似,transform可以与返回Series的函数一起使用,但结果必须和输入有相同的大小。如使用lambda函数给每个组乘以2

groupby python 两个 python groupby 两个变量_python_26

还可以按照每个组降序排序

groupby python 两个 python groupby 两个变量_groupby_27

定义一个标准化的函数

def normallize(x):
    return (x - x.mean()) / x.std()

df.groupby('key').transform(normallize)

 

groupby python 两个 python groupby 两个变量_字符串_28