# 分组后会得到一个新的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
----------------------------------------------------------------
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')
----------------------------------------------------------------
# 按照值类型分列
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
################
----------------------------------------------------------------
# 通过字典和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')}
----------------------------------------------------------------
# 通过函数进行分组
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
# 分组计算函数方法
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
----------------------------------------------------------------
min、max:非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
----------------------------------------------------------------
# 多函数计算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
----------------------------------------------------------------