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
----------------------------------------------------------------
推荐阅读
- EffectiveObjective-C2.0|EffectiveObjective-C2.0 笔记 - 第二部分
- 由浅入深理解AOP
- 继续努力,自主学习家庭Day135(20181015)
- python学习之|python学习之 实现QQ自动发送消息
- Android中的AES加密-下
- 逻辑回归的理解与python示例
- 一起来学习C语言的字符串转换函数
- python自定义封装带颜色的logging模块
- 【Leetcode/Python】001-Two|【Leetcode/Python】001-Two Sum
- 定制一套英文学习方案