Python学习笔记-数据分析-Pandas07—数据分组及相关操作

Pandas数据结构—数据分组及相关操作

一、分组 groupby
二、基本操作(一)
三、基本操作(二)
四、基本操作(三)
一、分组 groupby
groupby参数如下:
by=None, axis=0, level=None, as_index=True, sort=True, group_keys=True, squeeze=False, **kwargs
基本操作的一些方法:get_group() 、groups() 、size()、按数据类型分组、通过字典分组、通过Series分组、多函数计算agg()
二、基本操作(一)
# 分组后会得到一个新的dataframe
# axis参数模式 = 0,意思是以行来分组
# 多个列分组用([])来写

df = pd.DataFrame({'A' : ['python', 'java', 'python', 'java','python', 'C++', 'java', 'python'],
                   'B' : ['P', 'P', 'J', 'C', 'J', 'J', 'P', 'C'],
                   'C' : np.random.randn(8),
                   'D' : np.random.randn(8)})
print(df)
print('----------------------------------------------------------------')

# 注意:如果直接使用.groupby()这个方法,得到的只是一个groupby对象,它是一个中间数据,没有具体的数据内容呈现,
# 必须加入一个在.groupby()后面加上方法,才能进行计算。

# 根据A列进行分组
print('这是中间数据,没有具体的数据内容呈现:\n',df.groupby('A'))
print('----------------------------------------------------------------')

# 根据A列进行分组,并对分组进行求和
print('通过sum(),来呈现具体数据:\n',df.groupby('A').sum())
print('----------------------------------------------------------------')
# 根据A列进行分组,并对分组进行求平均
print('通过mean(),来呈现具体数据:\n',df.groupby('A').mean())
print('----------------------------------------------------------------')

# 根据A和B这两列同时分组。并对分组求和
a = df.groupby(['A','B']).sum()
print(a)
print('----------------------------------------------------------------')

# 根据A列进行分组,对D列求和,得到的结果只有D。
b = df.groupby(['A'])['D'].mean()
print(b)
print('----------------------------------------------------------------')

运行结果如下:

 A  B         C         D
0  python  P  1.464222  0.311215
1    java  P  0.094774 -0.550092
2  python  J -1.675885  1.092220
3    java  C -0.826553  0.193789
4  python  J -1.015872 -0.483023
5     C++  J  1.779017 -0.875131
6    java  P -0.897008  0.781554
7  python  C -1.198245 -0.479048
----------------------------------------------------------------
这是中间数据,没有具体的数据内容呈现:
 <pandas.core.groupby.DataFrameGroupBy object at 0x000001DDAFE312B0>
----------------------------------------------------------------
通过sum(),来呈现具体数据:
                C         D
A                         
C++     1.779017 -0.875131
java   -1.628787  0.425250
python -2.425780  0.441363
----------------------------------------------------------------
通过mean(),来呈现具体数据:
                C         D
A                         
C++     1.779017 -0.875131
java   -0.542929  0.141750
python -0.606445  0.110341
----------------------------------------------------------------
                 C         D
A      B                    
C++    J  1.779017 -0.875131
java   C -0.826553  0.193789
       P -0.802234  0.231462
python C -1.198245 -0.479048
       J -2.691757  0.609197
       P  1.464222  0.311215
----------------------------------------------------------------
A
C++      -0.875131
java      0.141750
python    0.110341
Name: D, dtype: float64
----------------------------------------------------------------
三、基本操作(二)get_group() 、groups() 、size()
df = pd.DataFrame({'X' : ['A', 'B', 'A', 'B'], 'Y' : [1, 2, 3, 4]})
print(df)
print('----------------------------------------------------------------')
print(df.groupby('X'))
print('----------------------------------------------------------------')
print(type(df.groupby('X')))
print('----------------------------------------------------------------')

# 通过list()将分组后的数据变成list,list中的元素是元组。
a = list(df.groupby('X'))

# 打印的结果会看着比较奇怪,打印出两个元组,其中元组的第一个元素是组名,第二元素其实是一个dataframe。
print(a)
print('----------------------------------------------------------------')

# 以元组的形式进行呈现。因为分成了A和B的两组,所以[0]呈现的是有A的组
print(a[0])
print('----------------------------------------------------------------')

# 有B的组
print(a[1])
print('----------------------------------------------------------------')

# 通过for循环读取分组中的各元素。
# n表示分组的成名,g表示分组里的数据。
for n,g in a:
    print(n)
    print(g)
    print(type(g))
    print('#####################')
print('----------------------------------------------------------------')

# 通过get_group()获得分组后的组
print('获得分组A:\n',df.groupby(['X']).get_group('A'))
print('----------------------------------------------------------------')
print('获得分组A:\n',df.groupby(['X']).get_group('B'))
print('----------------------------------------------------------------')

# 通过.groups将分组后的结果转为字典(dict),可用字典索引方法来查看groups里的元素
# 这里需要注意的是groups返回的是index。
dg = df.groupby(['X'])
print(dg.groups)
print('----------------------------------------------------------------')
print(dg.groups['A'])  
# 也可以写成下面这样
#print(df.groupby('X').groups['A'])
print('----------------------------------------------------------------')

# 通过.size()来查看分组后的长度
sz = dg.size()
print(sz)
print('----------------------------------------------------------------')
print(type(sz))
print('----------------------------------------------------------------')

# 按照两个列进行分组
df = pd.DataFrame({'A' : ['python', 'java', 'python', 'java','python', 'C++', 'java', 'python'],
                   'B' : ['P', 'P', 'J', 'C', 'J', 'J', 'P', 'C'],
                   'C' : np.random.randn(8),
                   'D' : np.random.randn(8)})
dg1 = df.groupby(['A','B']).groups
print(df)
print('----------------------------------------------------------------')

# 需要说明的是,因为没有分行,所以显示的结果看起来会比较乱。需要自己根据字典的格式来仔细查看结果。
print(dg1)
print('----------------------------------------------------------------')
print(dg1[('python', 'J')])
print('----------------------------------------------------------------')

运行结果如下:

 X  Y
0  A  1
1  B  2
2  A  3
3  B  4
----------------------------------------------------------------
<pandas.core.groupby.DataFrameGroupBy object at 0x000001DDB4CF2C18>
----------------------------------------------------------------
<class 'pandas.core.groupby.DataFrameGroupBy'>
----------------------------------------------------------------
[('A',    X  Y
0  A  1
2  A  3), ('B',    X  Y
1  B  2
3  B  4)]
----------------------------------------------------------------
('A',    X  Y
0  A  1
2  A  3)
----------------------------------------------------------------
('B',    X  Y
1  B  2
3  B  4)
----------------------------------------------------------------
A
   X  Y
0  A  1
2  A  3
<class 'pandas.core.frame.DataFrame'>
#####################
B
   X  Y
1  B  2
3  B  4
<class 'pandas.core.frame.DataFrame'>
#####################
----------------------------------------------------------------
获得分组A:
    X  Y
0  A  1
2  A  3
----------------------------------------------------------------
获得分组A:
    X  Y
1  B  2
3  B  4
----------------------------------------------------------------
{'A': Int64Index([0, 2], dtype='int64'), 'B': Int64Index([1, 3], dtype='int64')}
----------------------------------------------------------------
Int64Index([0, 2], dtype='int64')
----------------------------------------------------------------
X
A    2
B    2
dtype: int64
----------------------------------------------------------------
<class 'pandas.core.series.Series'>
----------------------------------------------------------------
        A  B         C         D
0  python  P -0.325400  1.196631
1    java  P -1.033418 -0.735083
2  python  J  0.464612 -0.611501
3    java  C -0.925026 -0.041456
4  python  J -1.275745  0.972651
5     C++  J -0.509822  0.858560
6    java  P -0.340469  0.865028
7  python  C -0.261158 -0.883880
----------------------------------------------------------------
{('C++', 'J'): Int64Index([5], dtype='int64'), ('java', 'C'): Int64Index([3], dtype='int64'), ('java', 'P'): Int64Index([1, 6], dtype='int64'), ('python', 'C'): Int64Index([7], dtype='int64'), ('python', 'J'): Int64Index([2, 4], dtype='int64'), ('python', 'P'): Int64Index([0], dtype='int64')}
----------------------------------------------------------------
Int64Index([2, 4], dtype='int64')
----------------------------------------------------------------
四、基本操作(三)
1、按照值类型分列
# 按照值类型分列
df = pd.DataFrame({'data1':np.random.rand(3),
                  'data2':np.random.rand(3),
                  'key1':['a','b','c'],
                  'key2':['one','two','three']})
print(df)
print('----------------------------------------------------------------')

# 通过dtypes来返回数据的类型
print(df.dtypes)
print('----------------------------------------------------------------')

# 依然使用groupby,但参数为df.dtypes,也就说按照类型分组。要注意一点要把axis参数设置为1。
# 默认情况下groupby是在axis=0方向(行方向)进行分组,可以指定axis=1方向(列方向)进行分组。
for n,p in df.groupby(df.dtypes, axis=1):
    print(n)
    print(p)
    print('################')
print('----------------------------------------------------------------')

运行结果如下:

data1     data2 key1   key2
0  0.764642  0.777184    a    one
1  0.587359  0.988120    b    two
2  0.523824  0.426143    c  three
----------------------------------------------------------------
data1    float64
data2    float64
key1      object
key2      object
dtype: object
----------------------------------------------------------------
float64
      data1     data2
0  0.764642  0.777184
1  0.587359  0.988120
2  0.523824  0.426143
################
object
  key1   key2
0    a    one
1    b    two
2    c  three
################
----------------------------------------------------------------
2、通过字典和Series分组
# 通过字典和Series分组
# 一般通过字典或者Series都是对列进行分组,根据行分组一般用不到。

df = pd.DataFrame(np.arange(20).reshape(4,5),
                  columns = ['a','b','c','d','e'])
print(df)
print('----------------------------------------------------------------')

# 定义一个字典,其中a、b列对应one,c、d列对应two,e列对应three
dict1 = {'a':'one','b':'one','c':'two','d':'two','e':'three'}
print(dict1)
print('----------------------------------------------------------------')
print(type(dict1))
print('----------------------------------------------------------------')

# 通过字典对df进行分组
by_column = df.groupby(dict1, axis = 1)

# 因为a和b对应的one所以,求和是会把a和b两列进行相加。c列和d列同理。e列因为是单独的,所以没什么变化。
print(by_column.sum())
print('----------------------------------------------------------------')

# 通过Series分组
# # s中,index中a、b对应one,c、d对应two,e对应three。
s = pd.Series(dict1)
print(s,'\n')
print('----------------------------------------------------------------')
print(s.groupby(s).count())
print('----------------------------------------------------------------')
# 通过groups看看,得到的结果是行的列标签。
print(s.groupby(s).groups)
print('----------------------------------------------------------------')

运行结果如下:

 a   b   c   d   e
0   0   1   2   3   4
1   5   6   7   8   9
2  10  11  12  13  14
3  15  16  17  18  19
----------------------------------------------------------------
{'a': 'one', 'b': 'one', 'c': 'two', 'd': 'two', 'e': 'three'}
----------------------------------------------------------------
<class 'dict'>
----------------------------------------------------------------
   one  three  two
0    1      4    5
1   11      9   15
2   21     14   25
3   31     19   35
----------------------------------------------------------------
a      one
b      one
c      two
d      two
e    three
dtype: object 

----------------------------------------------------------------
one      2
three    1
two      2
dtype: int64
----------------------------------------------------------------
{'one': Index(['a', 'b'], dtype='object'), 'three': Index(['e'], dtype='object'), 'two': Index(['c', 'd'], dtype='object')}
----------------------------------------------------------------
3、通过函数进行分组
# 通过函数进行分组
df = pd.DataFrame(np.arange(16).reshape(4,4),
                  columns = ['a','b','c','d'],
                 index = ['abc','bcd','aa','b'])
print(df,'\n')

# 按照字母长度分组,并对分组的结果进行求和
print(df.groupby(len).sum())

运行结果如下:

 a   b   c   d
abc   0   1   2   3
bcd   4   5   6   7
aa    8   9  10  11
b    12  13  14  15 

    a   b   c   d
1  12  13  14  15
2   8   9  10  11
3   4   6   8  10
4、分组计算函数方法
# 分组计算函数方法
s = pd.Series([1, 2, 3, 10, 20, 30], index = [1, 2, 3, 1, 2, 3])
grouped = s.groupby(level=0)  # 唯一索引用.groupby(level=0),将同一个index的分为一组
print(grouped)
print('first:非NaN的第一个值: \n',grouped.first())
print('last:非NaN的最后一个值: \n',grouped.last())
print('sum:非NaN的和: \n',grouped.sum())
print('mean:非NaN的平均值: \n',grouped.mean())
print('median:非NaN的算术中位数: \n',grouped.median())
print('count:非NaN的值: \n',grouped.count())
print('min、max:非NaN的最小值、最大值: \n',grouped.min())
print('std,var:非NaN的标准差和方差: \n',grouped.std())
print('prod:非NaN的积: \n',grouped.prod())

运行结果如下:

<pandas.core.groupby.SeriesGroupBy object at 0x000001DDB4CF2710>
----------------------------------------------------------------
first:非NaN的第一个值: 
 1    1
2    2
3    3
dtype: int64
----------------------------------------------------------------
last:非NaN的最后一个值: 
 1    10
2    20
3    30
dtype: int64
----------------------------------------------------------------
sum:非NaN的和: 
 1    11
2    22
3    33
dtype: int64
----------------------------------------------------------------
mean:非NaN的平均值: 
 1     5.5
2    11.0
3    16.5
dtype: float64
----------------------------------------------------------------
median:非NaN的算术中位数: 
 1     5.5
2    11.0
3    16.5
dtype: float64
----------------------------------------------------------------
count:非NaN的值: 
 1    2
2    2
3    2
dtype: int64
----------------------------------------------------------------
minmax:非NaN的最小值、最大值: 
 1    1
2    2
3    3
dtype: int64
----------------------------------------------------------------
std,var:非NaN的标准差和方差: 
 1     6.363961
2    12.727922
3    19.091883
dtype: float64
----------------------------------------------------------------
prod:非NaN的积: 
 1    10
2    40
3    90
dtype: int64
----------------------------------------------------------------
5、多函数计算agg()
# 多函数计算agg()
# agg函数里的写法可以用str,或者np.方法
# agg函数中的参数可以通过list,dict传入,当用dict时,key名为columns

df = pd.DataFrame({'a':[1,1,2,2],
                  'b':np.random.rand(4),
                  'c':np.random.rand(4),
                  'd':np.random.rand(4),})
print(df)
print('----------------------------------------------------------------')


# 以a进行分组,通过agg来进行 平均值与求和的两种计算
# a可以分成两组分别是1和2,然后对b c d进行计算。
print(df.groupby('a').agg(['mean',np.sum]))
print('----------------------------------------------------------------')

# 以a进行分组,单独显示b列的结果。
print(df.groupby('a')['b'].agg({'result1':np.mean,
                               'result2':np.sum}))
print('----------------------------------------------------------------')

运行结果如下:

 a         b         c         d
0  1  0.008648  0.434679  0.642889
1  1  0.408283  0.240458  0.539475
2  2  0.392103  0.533814  0.406897
3  2  0.217749  0.631762  0.025736
----------------------------------------------------------------
          b                   c                   d          
       mean       sum      mean       sum      mean       sum
a                                                            
1  0.208465  0.416931  0.337569  0.675137  0.591182  1.182363
2  0.304926  0.609853  0.582788  1.165576  0.216316  0.432633
----------------------------------------------------------------
    result1   result2
a                    
1  0.208465  0.416931
2  0.304926  0.609853
----------------------------------------------------------------

你可能感兴趣的:(Python学习笔记-数据分析-Pandas07—数据分组及相关操作)