pandas

一、Series(一维数据)(创建、查找、属性、日期类型数据)

Series可以理解为一个一维的数组,只是index名称可以自己改动。类似于定长的有序字典,有Index和 value。

个人理解,Series生成的是行数的一维数组,

的一维数组是指列数的一维数组。因为二维数组,如果将一维数组转为二维数组,是一行一行的填充,将数充满整个数组!

1、创建(空/Series(ndarray)/字典/标量

1)创建空Serise
import pandas as pd
s=pd.Serier()
##注意括号
##创建一个空的Series
2)Series通过ndarray创建一个Series
import pandas as pd
import numpy as py
data=np.arrary(['张三','李四','王五','赵柳'])
s=pd.Series(data)
#这里默认生成0-3的行级索引
s=pd.Series(data,index=['100','101','102','103'])
#这里可以通过给index赋值,生成对应的索引
3)通过字典创建一个Series(字典的键作为行的索引名,字典值作为数据值)
import pandas as pd
data = {'100' : '张三', '101' : '李四', '102' : '王五'}
s = pd.Series(data)
4)通过标量创建Series(可以创建同样数字的,不同行数的Series。可以通过index=[]、index=range()、index=np.arrary())
import pandas as pd
import numpy as np
s = pd.Series(5, index=[0, 1, 2, 3])
s = pd.Series(5, index=range(101))
s = pd.Series(5, index=np.array(101))

2、查找

1)通过索引
# 使用索引检索元素
import pandas as pd
s = pd.Series([1,2,3,4,5],index = ['a','b','c','d','e'])
print(s[0], s[:3], s[-3:])
2)通过标签名(切片是左右都包含的)
import pandas as pd
s = pd.Series([1,2,3,4,5],index = ['a','b','c','d','e'])
# 使用标签检索数据
print(s['a'], s['a':'d'])
通过标签名拿到的索引,是左右元素都包含的,与索引切片不同!

索引切片与标签切片的区别!
使用索引位置切片: end不会拿到
使用索引名字切片: end会拿到的
s[0:3]
s[‘a’:‘c’]

3)索引/标签掩码数组Series(可以间隔显示行的数据)

格式: s.[[]] 列表嵌套列表,其中列表可以是切片也可以是需要显示的行的索引/标签

import pandas as pd
#也可以用于索引掩码数组    
#区分与numpy中的掩码数组,numpy中的掩码数组一般是通过bool值来将不需要的数据盖掉
s = pd.Series([1,2,3,4,5],index = ['a','b','c','d','e'])
print(S[[0,2,3]])#0 2 3是索引
print(S[['zs','ww','zq']])#'zs','ww','zq' 是标签

3、属性

s1.values

所有的值 返回一个ndarray数组,一维数组

s1.index

所有的索引 返回索引对象,可迭代对象!!需要循环才可以打印出来 for i in s.index:

print(s[i]) -->可以逐步打印每一行的值

s1.dtype

数据类型

s1.size

数据个数

s1.ndim

数据维数

s1.shape

数据维度

4、日期类型数据处理(将别的数据类型,如ndarray中的数组的日期类型的数据转为pandas的Series日期类型)

1)接口:pd.to_datetime(dates)
-
通过date=pd.datetime(2020,01,01)可以生成>>>2020-01-01 00:00:00  但是运行时程序会有警告!

# pandas识别的日期字符串格式
dates = pd.Series(['2011', '2011-02', '2011-03-01', '2011/04/01', 
                   '2011/05/01 01:01:01', '01 Jun 2011','Jun 01 2011',
                   '20110701','2011/8/1'])
					只要数字的数量能对上年月日,以及英文,都可以转为日期类型,
    				果是940922识别会出问题!


# to_datetime() 转换日期数据类型
dates = pd.to_datetime(dates)
print(dates, dates.dtype, type(dates))
# 获取时间的某个日历字段的数值
print(dates.dt.day)

Series.dt提供了很多日期相关操作(经过pd.to_datetime()提取后的才可以用这些属性,

如下: 提取时间类型的年月日时分秒等

Series.dt.year	The year of the datetime.  年
Series.dt.month	The month as January=1, December=12.  月
Series.dt.day	The days of the datetime. 日
Series.dt.hour	The hours of the datetime. 时
Series.dt.minute	The minutes of the datetime. 分
Series.dt.second	The seconds of the datetime. 秒
Series.dt.microsecond	The microseconds of the datetime. 微秒
Series.dt.week	The week ordinal of the year. 一年当中的第几周
Series.dt.weekofyear	The week ordinal of the year.一年当中的第几周
Series.dt.dayofweek	The day of the week with Monday=0, Sunday=6. 星期几
Series.dt.weekday	The day of the week with Monday=0, Sunday=6.星期几
Series.dt.dayofyear	The ordinal day of the year. 一年当中的第几天
Series.dt.quarter	The quarter of the date. 季度
Series.dt.is_month_start	Indicates whether the date is the first day of the month.
Series.dt.is_month_end	Indicates whether the date is the last day of the month.
Series.dt.is_quarter_start	Indicator for whether the date is the first day of a quarter.
Series.dt.is_quarter_end	Indicator for whether the date is the last day of a quarter.
Series.dt.is_year_start	Indicate whether the date is the first day of a year.
Series.dt.is_year_end	Indicate whether the date is the last day of the year.
Series.dt.is_leap_year	Boolean indicator if the date belongs to a leap year.
Series.dt.days_in_month	The number of days in the month.
2)日期运算
# datetime日期运算
delta = dates - pd.to_datetime('1970-01-01')
print(delta, delta.dtype, type(delta))
# 把时间偏移量换算成天数
print(delta.dt.days)   
#只能看days其他的不行,与查看天数不同,这个是复数,上面的是day单数的形式
3)date_range()生成指定的周期和频率的Series日期
3.1)date_range(date,periods= ,freq=‘D’)
import pandas as pd
# 以日为频率
datelist = pd.date_range('2019/08/21', periods=5)
print(datelist)
# 以月为频率  生成的是每个月最后一天的日期!!!不是月初   #指定的日期只有含有月份即可,不管有没有日期
datelist = pd.date_range('2020/01/21', periods=5,freq='M')
print(datelist)
>>DatetimeIndex(['2020-01-31', '2020-02-29', '2020-03-31', '2020-04-30',
               '2020-05-31'],
              dtype='datetime64[ns]', freq='M')
#以年为频率,生成的也是每年的最后一天,然后递增!!!  指定的日期只要有年份即可,生成的都是含年月日的日期
datalist=pd.date_range('2020-01-31',periods=5,freq='Y')
print(datalist)
>>>atetimeIndex(['2020-12-31', '2021-12-31', '2022-12-31', '2023-12-31','2024-12-31'],dtype='datetime64[ns]', freq='A-DEC')

## 构建某个区间的时间序列
start = pd.datetime(2017, 11, 1)
end = pd.datetime(2017, 11, 5)
dates = pd.date_range(start, end)
print(dates)


#特殊,生成商业时间:
freq = 'B'
`bdate_range()`用来表示商业日期范围,不同于`date_range()`,它不包括星期六和星期天。
import pandas as pd
datelist = pd.bdate_range('2011/11/03', periods=5)
print(datelist)
3.2)date_range(star,end) 构建某个区间的时间序列
import pandas as pd
start = pd.datetime(2017, 11, 1)
end = pd.datetime(2017, 11, 5)
dates = pd.date_range(start, end)
print(dates)

二、DataFrame(二维数据)(创建/属性/数据增删改查/复合索引!数据合并)

DataFrame是一个类似于表格(有行有列)的数据类型,可以理解为一个二维数组,索引有两个维度(行级索引,列级索引),可更改。

DataFrame具有以下特点:

  • 列和列之间可以是不同的类型 :不同的列的数据类型可以不同
  • 大小可变 (扩容)
  • 标记轴(行级索引 和 列级索引)
  • 针对行与列进行轴向统计(水平,垂直)

1、创建(空/列表嵌套(列表/字典)/字典)

1)创建空DataFrame
import pandas as pd
# 创建一个空的DataFrame
df = pd.DataFrame()
print(df)
2)列表创建DataFrame(嵌套列表,嵌套字典)

2.1)单列表

import pandas as pd
data = [1,2,3,4,5]  一维列表   #5行1列
df = pd.DataFrame(data)
print(df)
>>>生成5行1列的的列表

2.2)列表嵌套列表[[],[],[]](一个列表元素代表一条记录,即行)

import pandas as pd
data = [['Alex',10],['Bob',12],['Clarke',13]]
df = pd.DataFrame(data,index=[s01,s02,s03],columns=['Name','Age'])
df = pd.DataFrame(data,columns=['Name','Age'])
print(df)

data = [['Alex',10],['Bob',12],['Clarke',13]]
df = pd.DataFrame(data,columns=['Name','Age'],dtype=float)
print(df)

#index代表的是行级索引,可以自定义,columns是列表索引,也是可以修改,如果不指定,默认从0开始作为索引的起始值!也可以通过dtype修改数据的类型

2.3)列表嵌套字典[{},{},{}](一个列表元素作为一条记录,字典内的键作为列的索引,字典的值作为值)

data = [{'a': 1, 'b': 2},{'a': 5, 'b': 10, 'c': 20}]
df = pd.DataFrame(data)
print(df)

#这里体现的就是可扩容
#这里的一个字典代表一行数据,键作为列级索引,如果不存在的键,则自动填充NAN(not a number)

3)字典创建DataFrame({ key1:[value1],key2:[value2] })

通过字典创建DataFrame,字典的键作为列的索引,而字典的值作为该列的值。这里需要分两种情况,值的类型,如果是正常的列表数值结构,需要字典间各个元素的value长度一致,如果是通过Series创建的值,则可以长度不一致,通过NaN来补充

3.1)字典的值是一般的列表数据

data = {'Name':['Tom', 'Jack', 'Steve', 'Ricky'],'Age':[28,34,29,42]}
df = pd.DataFrame(data, index=['s1','s2','s3','s4'])
print(df)
# 这里的字典元素之间的值需要长度一致,不然会报错!

3.2)字典的值是Series类型的数据

data = {'one' : pd.Series([1, 2, 3], index=['a', 'b', 'c']),
        'two' : pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd'])}
df = pd.DataFrame(data)
print(df)
>>>这里会在第四列中的第一个元素添加NaN。可以通过指定的列名来确定NaN的位置!

data = {'one' : pd.Series([1, 2, 3], index=['a', 'c', 'd']),
        'two' : pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd'])}
df = pd.DataFrame(data)
print(df)
>>>这里会在第二列中的第一个元素添加NaN。可以通过指定的列名来确定NaN的位置
从字典来创建DataFrame 字典的值不一致,通过Series来补充NAN,默认是在最后补充NAN,如果需要在指定的位置添加NAN,需要通过给行做索引来对应值,添加index值

2、常用属性

编号

属性或方法

描述

1

axis

返回 行/列 标签(index)列表。

2

columns

返回列标签

3

index

返回行标签

4

dtype

返回对象的数据类型(dtype)。

5

empty

如果系列为空,则返回True

6

ndim

返回底层数据的维数,默认定义:1

7

size

返回基础数据中的元素数。

8

values

将系列作为ndarray返回。

9

head(n)

返回前n行。

10

tail(n)

返回最后n行。

import pandas as pd

data = {'Name':['Tom', 'Jack', 'Steve', 'Ricky'],'Age':[28,34,29,42]}
df = pd.DataFrame(data, index=['s1','s2','s3','s4'])
df['score']=pd.Series([90, 80, 70, 60], index=['s1','s2','s3','s4'])
print(df)
print(df.axes)
print(df['Age'].dtype)
print(df.empty)   
print(df.ndim)
print(df.size)
print(df.values)
print(df.head(3)) # df的前三行
print(df.tail(3)) # df的后三行

3、行和列的增删改查

3.1)列的增删改查
3.1.1列的查找/访问 #通过索引 df[[‘列名’,‘列名’]] 、df[df.columns[:2]]

DataFrame的单列数据为一个Series。根据DataFrame的定义可以 知晓DataFrame是一个带有标签的二维数组,每个标签相当每一列的列名。

d = {'one' : pd.Series([1, 2, 3], index=['a', 'b', 'c']),
     'two' : pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd']), 
     'three' : pd.Series([1, 3, 4], index=['a', 'c', 'd'])}

df = pd.DataFrame(d)

#通过列名,可以访问到列的内容,如果是多列,则添加多个列名。
#df.columns[:2]获取的是列名!
df['one']
df[df.columns[:2]]
3.1.2列的添加

DataFrame添加一列的方法非常简单,只需要新建一个列索引。并对该索引下的数据进行赋值操作即可。

类似字典添加值的操作。df[‘列名’]=pd.Series([ num,num1,],index=)

#需要注意的一点是,新添加的列,如果是Series类型,需要和原来的列表的行索引即index一致**,如果不一致,无法将数据添加上去,不报错,添加了NAN。如果添加的是列表,只需要保证列的长度和dataframe的行数一致!!如果不一致,则报错。

import pandas as pd

df['four']=pd.Series([90, 80, 70, 60], index=['a', 'b', 'c', 'd'])
print(df)

注意:
	创建新的列时,要给出原有dataframe的index
3.1.3列的删除(del pop drop)
1)del(df[‘列名’]) #只能删除一列
2)df.pop(‘列名’) #只能删除一列

#调用pop方法删除一列 这里也会返回被删除的值 用法和列表一致!!!

3)df.drop([‘列名’,‘列名’,…],axis=0/1,inplace=False) #不删除原数据

#多列删除,但是不会删除原数据,而是生成一个新的删除了指定的列的数据。

axis=0是指删除行

axis=1是指删除列

inplace=False,默认值是False,则是在生成新的数据,在新的数据上进行删除。如果是inplace=True,则是在原来的数据上进行修改!

import pandas as pd

d = {'one' : pd.Series([1, 2, 3], index=['a', 'b', 'c']), 
     'two' : pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd']), 
     'three' : pd.Series([10, 20, 30], index=['a', 'b', 'c'])}
df = pd.DataFrame(d)
print("dataframe is:")
print(df)

# 删除一列: one
del(df['one'])
print(df)

#调用pop方法删除一列  这里也会返回被删除的值  用法和列表一致!!!
df.pop('two')
print(df)

#如果想要删除多列呢?  axis=0默认的意思是水平方向!
#删除多列  drop 轴向axis=1是必须给的    默认axis=0删除行的 ,不会修改原数据。
#所以需要用一个变量去接收,只是用来显示数据!!
#如果需要筛选数据,去掉少数几列,可以通过返回值来看到剩余的数据!,而且不影响原数据
df2 = df.drop(['one','four'],axis=1)
print(df2)
3.2) 行的增删改查
3.2.1)行的查找/访问 #通过切片 df[:2] df.loc[’index’] df.iloc[‘标签名’]

如果只是需要访问DataFrame某几行数据的实现方式则采用数组的选取方式,使用 “:” 即可:

对于dataframe

loc函数:通过行索引 “Index” 中的具体值来取行数据(如取"Index"为"A"的行

iloc函数:通过行号来取行数据(如取第二行的数据

直接索引:访问的是列
直接切片:访问的是行

#通过切片访问的,如果Series一样,如果切片是标签,最后一个会拿到,
#如果是下标,最后一个不会拿到
import pandas as pd

d = {'one' : pd.Series([1, 2, 3], index=['a', 'b', 'c']), 
    'two' : pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd'])}

df = pd.DataFrame(d)
print(df[2:4])
print(df['a':'c'])

loc是针对DataFrame索引名称的切片方法。loc方法使用方法如下:

只支持索引名称,不支持索引位置。

import pandas as pd

d = {'one' : pd.Series([1, 2, 3], index=['a', 'b', 'c']), 
     'two' : pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd'])}

df = pd.DataFrame(d)
print(df.loc['b']) #返回的是series!!
print(df.loc['a':'c'])#返回的是a-c的行列式
print(df.loc[['a', 'b']])#可以返回'a'和'b'行,也可以间隔开来

注意区别loc和iloc行索引和列索引的位置

iloc和loc区别是iloc接收的必须是行索引和列索引的位置(数字下标,不是标签,索引值)。iloc方法的使用方法如下:

import pandas as pd

d = {'one' : pd.Series([1, 2, 3], index=['a', 'b', 'c']),
     'two' : pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd'])}

df = pd.DataFrame(d)
print(df.iloc[2])
print(df.iloc[[2, 3]])#列表嵌套列表的是显示不同行

##注意区别,print(df.iloc[2])/print(df.iloc[2:3])
print(df.iloc[2])>>>返回的是series  与loc一样
print(df.iloc[2:3])>>>这个返回的是横着的一行的数据,不是series
3.2.2)行的添加 (df.append())
import pandas as pd

df = pd.DataFrame([['zs', 12], ['ls', 4]], columns = ['Name','Age'])
df2 = pd.DataFrame([['ww', 16], ['zl', 8]], columns = ['Name','Age'])

df = df.append(df2)#四行两列
print(df)
####
df = pd.DataFrame([['zs', 12], ['ls', 4]], columns = ['Name','Age'])
df2 = pd.DataFrame([['ww', 16], ['zl', 8]], columns = ['name','age'])

df = df.append(df2)  #四行四列,因为列的名字不一样
print(df)
3.2.3)行的删除 drop(索引/标签名,axis=0,inplace=True)

使用索引标签从DataFrame中删除或删除行。 如果标签重复,则会删除多行。

import pandas as pd

df = pd.DataFrame([['zs', 12], ['ls', 4]], columns = ['Name','Age'])
df2 = pd.DataFrame([['ww', 16], ['zl', 8]], columns = ['Name','Age'])
df = df.append(df2)
# 删除index为0的行   原数据不会被修改,需要新的变量去接收
df = df.drop(0)
print(df)
#也可以通过删除标签名来删除行,df.drop['a']

#如果需要通过drop修改原数据,可以通过修改drop中的一个参数,inplace。inplace=False默认不修改原数据
#如果将inplace=True 则会直接修改原数据。也不需要新的变量去接收,直接修改原数据
df = df.drop(0,axis=0,inplace=True)#将第0行在原数据中删除!!
3.3)行或列的修改(只有通过列找行才能修改成功)

修改DataFrame中的数据 (访问)(只能通过列找行才能修改成功)

更改DataFrame中的数据,原理是将这部分数据提取出来,重新赋值为新的数据。

import pandas as pd

df = pd.DataFrame([['zs', 12], ['ls', 4]], columns = ['Name','Age'])
df2 = pd.DataFrame([['ww', 16], ['zl', 8]], columns = ['Name','Age'])
df = df.append(df2)
df['Name'][0] = 'Tom'
print(df)

#如果想要通过访问数据,赋值修改的话
# 只能采用通过列,找行的方式,(但是修改的过程会有警告)因为底层有赋值的过程    #先列再行 

# 如果通过行找列,因为底层没有赋值的过程,所以没有效果,不会修改成功

4、复合索引

DataFrame的行级索引与列级索引都可以设置为复合索引,表示从不同的角度记录数据。

scroes                 info 
			  Chinese   Math   English   age     weight
classA    M     100      100     100      18       80
                 F     120      120     120      18       50
 
classB    M     101      101     101      18       90
                 F     121      121     121      18       45

 classC   M     102      102     102      18       70
                F     122      122     122      18       55
data = np.floor(np.random.normal(85, 3, (6,3)))
	np.floor  向下取整
    np.random 随机数模块
    np.random.normal 正态分布  :钟形曲线 
    
    85期望值
    3 标准差     标准差越大,数据波动越大
                标准差越小,数据波动越小
    (6,3) 维度
    
    
df = pd.DataFrame(data)
index = [('classA', 'F'), ('classA', 'M'), ('classB', 'F'), ('classB', 'M'), ('classC', 'F'), ('classC', 'M')]

df.index = pd.c.from_tuples(index)
columns = [('Age', '20+'), ('Age', '30+'), ('Age', '40+')]
df.columns = pd.MultiIndex.from_tuples(columns)

复合索引的访问:同行列的访问的一样

# 访问行
df.loc['classA']
df.loc['classA', 'F']
df.loc[['classA', 'classC']]

# 访问列
df.Age
df.Age['20+']
df['Age']
df['Age', '20+']

5、数据合并(concat、merge & join)

5.1)concat()

concat函数是在pandas的方法,可以根据不同的轴合并数据集。

根据axis=0/1来进行纵向合并(行合并)和横向合并(列合并)!

#合并不同的DataFrame根据实际的列名和index名合并,没有共同的会自动补充NaN

参考:https://www.pypandas.cn/docs/user_guide/merging.html#concatenating-objects

r = pd.concat(datas, axis=0, join='outer', ignore_index=False, 
              keys=['x', 'y', 'z'])
axis=0  纵向合并   默认值为0
axis=1  横向合并
join='outer'  表示并集   默认值是outer
join='inner'  表示并集
ignore_index 默认值是False  使用原本的index索引,如果设置为True则将所有的index 索引重新编号为0-n
keys  复合索引,如果需要对每个合并前的数据做索引标记,则需要用keys


#关于横向合并,也就是行的合并,可以使用append的方式将多个数据合并到一起,其他参数,也适用,如ignore_index,keys等
result= df1.append(df2)
result= df1.append([df2, df3])
5.2)merge&join

panda具有全功能、高性能的内存连接操作,与SQL之类的关系数据库非常相似。与其他开源实现相比,这些方法的性能要好得多(在某些情况下要好一个数量级以上)

pandas提供了merge函数实现高效的内存链接操作:

#注意,这里默认的一般是通过列名相同来进行合并,如果需要将行进行合并,需要注意参数left_index和right_index,这两个参数一般一起搭配使用,如果是True指用原来的index,如果是False则是重新对索引进行编号!

pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None,left_index=False, right_index=False)

参数名称

说明

left

接收DataFrame或Series。表示要添加的新数据。无默认。

right

接收DataFrame或Series。表示要添加的新数据。无默认。。

how

接收inner,outer,left,right。表示数据的连接方式。默认为inner。

on

接收string或sequence。表示外键字段名。默认为None。 #自动寻找相同列表名的字段作为连接关键字

left_on

接收string或sequence。关联操作时左表中的关联字段名。

right_on

接收string或sequence。关联操作时右表中的关联字段名。

left_index

接收boolean。表示是否将left参数接收数据的index作为连接主键。默认为False。

right_index

接收boolean。表示是否将right参数接收数据的index作为连接主键。默认为False。

sort

接收boolean。表示是否根据连接键对合并后的数据进行排序。默认为False。

suffixes

接收接收tuple。表示用于追加到left和right参数接收数据重叠列名的尾缀默认为(’_x’, ‘_y’)。

其他合并方法同数据库相同:

合并方法

SQL等效

描述

left

LEFT OUTER JOIN

使用左侧对象的键 #左外连接,保留左表中的数据,连不上的也会显示,自动绑定NaN

right

RIGHT OUTER JOIN

使用右侧对象的键 #右外连接,保留右表中的数据,连不上的也会显示,自动绑定NaN

outer

FULL OUTER JOIN

使用键的联合 #外连接,只要有的,都能显示,连不上的自动绑定NaN

inner

INNER JOIN

使用键的交集 #内连接,只返回连上的数据

实验:

# 合并两个DataFrame (左连接)
rs = pd.merge(left,right,on='subject_id', how='right')
print(rs)
# 合并两个DataFrame (左连接)
rs = pd.merge(left,right,on='subject_id', how='outer')
print(rs)
# 合并两个DataFrame (左连接)
rs = pd.merge(left,right,on='subject_id', how='inner')
print(rs)

6、分组聚合(groupby、apply)

pandas提供了功能类似于数据库中group by语句的用于拆分(spilt)数据组的方法pd.groupby();该方法提供的是分组聚合步骤中的拆分功能,能根据索引或字段对数据进行分组(Split) 进而针对得到的多组数据执行聚合操作(Apply),最终合并为最终结果(Combine)。

过程:

分组聚合:分组、聚合、输出结果

6.1)分组 df.groupby(by= ,axis=,as_index,sort=)

groupby方法的参数及其说明:

DataFrame.groupby(by=None, axis=0, as_index=True, sort=True)

参数名称

说明

by

接收list,string,mapping或generator。用于确定进行分组的依据。无默认。

axis

接收int。表示操作的轴向,默认对行进行操作。默认为0。

as_index

接收boolearn。表示聚合后的聚合标签是否以DataFrame索引形式输出。默认为True。

sort

接收boolearn。表示是否对分组依据分组标签进行排序。默认为True。

用groupby方法分组后的结果并不能直接查看,而是被存在内存中,输出的是内存地址。实际上分组后的数据对象(Groupby对象)类似Series与DataFrame,是pandas提供的一种对象。

Groupby对象的常用方法:

方法

说明

groupObject.get_group(‘A’)

返回A组的详细数据

groupObject.size()

返回每一组的频数

grouped = data.groupby(by=['class_id', 'gender'])
grouped.get_group((1, 'M'))
grouped = data.groupby(by=['class_id', 'gender'])
grouped.get_group((1, 'M'))
6.2)聚合 grouped.agg()

聚合函数为每个组返回聚合值。当创建了分组(groupby)对象,就可以对每个分组的其他字段数据执行求和、求标准差等操作。

对于某个字段希望只做求均值操作,而对另一个字段则希望只做求和操作,可以使用字典的方式,将两个字段名分别作为key:

grouped['score'].agg({'age':np.max, 'score':np.mean})

还可以这样:

result = grouped['score'].agg(
    {'age':np.max, 'score':[np.mean, np.max]})
result

先通过group_by进行分组,拿到分组对象 by:通过那个字段进行分组

size:求每组的频数

get_group() :查看每组的数据

在用过 agg进行聚合,传入一个字典:每个键值对就是对字段进行的聚合操作

pandas支持的聚合函数有:

方法名称

说明

count

计算分组的数目,包括缺失值。

head

返回每组的前n个值。

max

返回每组最大值。

mean

返回每组的均值。

median

返回每组的中位数。

cumcount

对每个分组中组员的进行标记,0至n-1。

size

返回每组的大小。

min

返回每组最小值。

std

返回每组的标准差。

sum

返回每组的和。

7、透视表

透视表(pivot table)是各种电子表格程序和其他数据分析软件中一种常见的数据汇总工具。它根据一个或多个键对数据进行分组聚合,并根据每个分组进行数据汇总

在某些程度上:透视表比groupby&agg代码更简单

透视表不能完全的替代groupby&agg

groupby&agg 一次可以做多种聚合

透视表一次只能做一个

##透视表的聚合操作,默认的是均值聚合!

##如果没有给显示指定的列,会将原数据中的所有数值列都做均值操作,并显示

# 以class_id与gender做分组汇总数据,默认聚合统计所有列
print(data.pivot_table(index=['class_id', 'gender']))

# 以class_id与gender做分组汇总数据,聚合统计score列
print(data.pivot_table(index=['class_id', 'gender'], values=['score']))

# 以class_id与gender做分组汇总数据,聚合统计score列,针对age的每个值列级分组统计
print(data.pivot_table(index=['class_id', 'gender'], values=['score'], columns=['age']))

# 以class_id与gender做分组汇总数据,聚合统计score列,针对age的每个值列级分组统计,添加行、列小计-->这个也是均值!!!
print(data.pivot_table(index=['class_id', 'gender'], values=['score'], columns=['age'], margins=True))

# 以class_id与gender做分组汇总数据,聚合统计score列,针对age的每个值列级分组统计,添加行、列小计
print(data.pivot_table(index=['class_id', 'gender'], values=['score'],  columns=['age'], margins=True, aggfunc='max'))#-->aggfunc指定分组的想要的类型,比如,均值,最大值,最小值,标准差

#group by/pivot_table,聚合后的计算,pivot_table只能用一种计算方式,而group by可以做不同类型的操作!