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('----------------------------------------------------------------')

运行结果如下:
ABCD 0pythonP1.4642220.311215 1javaP0.094774 -0.550092 2pythonJ -1.6758851.092220 3javaC -0.8265530.193789 4pythonJ -1.015872 -0.483023 5C++J1.779017 -0.875131 6javaP -0.8970080.781554 7pythonC -1.198245 -0.479048 ---------------------------------------------------------------- 这是中间数据,没有具体的数据内容呈现: ---------------------------------------------------------------- 通过sum(),来呈现具体数据: CD A C++1.779017 -0.875131 java-1.6287870.425250 python -2.4257800.441363 ---------------------------------------------------------------- 通过mean(),来呈现具体数据: CD A C++1.779017 -0.875131 java-0.5429290.141750 python -0.6064450.110341 ---------------------------------------------------------------- CD AB C++J1.779017 -0.875131 javaC -0.8265530.193789 P -0.8022340.231462 python C -1.198245 -0.479048 J -2.6917570.609197 P1.4642220.311215 ---------------------------------------------------------------- A C++-0.875131 java0.141750 python0.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('----------------------------------------------------------------')

运行结果如下:
XY 0A1 1B2 2A3 3B4 -------------------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------- [('A',XY 0A1 2A3), ('B',XY 1B2 3B4)] ---------------------------------------------------------------- ('A',XY 0A1 2A3) ---------------------------------------------------------------- ('B',XY 1B2 3B4) ---------------------------------------------------------------- A XY 0A1 2A3 ##################### B XY 1B2 3B4 ##################### ---------------------------------------------------------------- 获得分组A: XY 0A1 2A3 ---------------------------------------------------------------- 获得分组A: XY 1B2 3B4 ---------------------------------------------------------------- {'A': Int64Index([0, 2], dtype='int64'), 'B': Int64Index([1, 3], dtype='int64')} ---------------------------------------------------------------- Int64Index([0, 2], dtype='int64') ---------------------------------------------------------------- X A2 B2 dtype: int64 ---------------------------------------------------------------- ---------------------------------------------------------------- ABCD 0pythonP -0.3254001.196631 1javaP -1.033418 -0.735083 2pythonJ0.464612 -0.611501 3javaC -0.925026 -0.041456 4pythonJ -1.2757450.972651 5C++J -0.5098220.858560 6javaP -0.3404690.865028 7pythonC -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('----------------------------------------------------------------')

运行结果如下:
data1data2 key1key2 00.7646420.777184aone 10.5873590.988120btwo 20.5238240.426143cthree ---------------------------------------------------------------- data1float64 data2float64 key1object key2object dtype: object ---------------------------------------------------------------- float64 data1data2 00.7646420.777184 10.5873590.988120 20.5238240.426143 ################ object key1key2 0aone 1btwo 2cthree ################ ----------------------------------------------------------------

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('----------------------------------------------------------------')

运行结果如下:
abcde 001234 156789 21011121314 31516171819 ---------------------------------------------------------------- {'a': 'one', 'b': 'one', 'c': 'two', 'd': 'two', 'e': 'three'} ---------------------------------------------------------------- ---------------------------------------------------------------- onethreetwo 0145 111915 2211425 3311935 ---------------------------------------------------------------- aone bone ctwo dtwo ethree dtype: object ---------------------------------------------------------------- one2 three1 two2 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())

运行结果如下:
abcd abc0123 bcd4567 aa891011 b12131415 abcd 112131415 2891011 346810

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())

运行结果如下:
---------------------------------------------------------------- first:非NaN的第一个值: 11 22 33 dtype: int64 ---------------------------------------------------------------- last:非NaN的最后一个值: 110 220 330 dtype: int64 ---------------------------------------------------------------- sum:非NaN的和: 111 222 333 dtype: int64 ---------------------------------------------------------------- mean:非NaN的平均值: 15.5 211.0 316.5 dtype: float64 ---------------------------------------------------------------- median:非NaN的算术中位数: 15.5 211.0 316.5 dtype: float64 ---------------------------------------------------------------- count:非NaN的值: 12 22 32 dtype: int64 ---------------------------------------------------------------- min、max:非NaN的最小值、最大值: 11 22 33 dtype: int64 ---------------------------------------------------------------- std,var:非NaN的标准差和方差: 16.363961 212.727922 319.091883 dtype: float64 ---------------------------------------------------------------- prod:非NaN的积: 110 240 390 dtype: int64 ----------------------------------------------------------------

5、多函数计算agg()
# 多函数计算agg() # agg函数里的写法可以用str,或者np.方法 # agg函数中的参数可以通过list,dict传入,当用dict时,key名为columnsdf = 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('----------------------------------------------------------------')

【Python学习笔记-数据分析-Pandas07—数据分组及相关操作】运行结果如下:
abcd 010.0086480.4346790.642889 110.4082830.2404580.539475 220.3921030.5338140.406897 320.2177490.6317620.025736 ---------------------------------------------------------------- bcd meansummeansummeansum a 10.2084650.4169310.3375690.6751370.5911821.182363 20.3049260.6098530.5827881.1655760.2163160.432633 ---------------------------------------------------------------- result1result2 a 10.2084650.416931 20.3049260.609853 ----------------------------------------------------------------

    推荐阅读