Pandas数据结构Series:基本概念及创建
# Series 数据结构
# Series 是带有标签的一维数组,可以保存任何数据类型(整数,字符串,浮点数,Python对象等),轴标签统称为索引
import numpy as np
import pandas as pd
# 导入numpy、pandas模块
ar = np.random.rand(5)
s = pd.Series(ar)
ss = pd.Series(ar,index=list('abcde'))#修改index的值
print(ar)
print(s)
print(type(s))
print(ss)
# 查看数据、数据类型
print(s.index,type(s.index))# .index查看series索引,类型为rangeindex
print(s.values,type(s.values))# .values查看series值,类型是ndarray
# 核心:series相比于ndarray,是一个自带索引index的数组 → 一维数组 + 对应索引
# 所以当只看series的值的时候,就是一个ndarray
# series和ndarray较相似,索引切片功能差别不大
# series和dict相比,series更像一个有顺序的字典(dict本身不存在顺序),其索引原理与字典相似(一个用key,一个用index)
# Series 创建方法一:由字典创建,字典的key就是index,values就是values
dic = {
'a':1 ,'b':2 , 'c':3, '4':4, '5':5}
s = pd.Series(dic)
print(s)
# 注意:key肯定是字符串,假如values类型不止一个会怎么样? →
dic2 = {
'a':1 ,'b':'hello' , 'c':3, '4':4, '5':5}
s2 = pd.Series(dic2)
print(s2)
# Series 创建方法二:由数组创建(一维数组)
arr = np.random.randn(5)
s = pd.Series(arr)
print(arr)
print(s)
# 默认index是从0开始,步长为1的数字
s = pd.Series(arr, index = ['a','b','c','d','e'],dtype = np.object)
print(s)
# index参数:设置index,长度保持一致
# dtype参数:设置数值类型
# Series 创建方法三:由标量创建
s = pd.Series(10, index = range(4))
print(s)
# 如果data是标量值,则必须提供索引。该值会重复,来匹配索引的长度
# Series 名称属性:name
s1 = pd.Series(np.random.randn(5))
print(s1)
print('-----')
s2 = pd.Series(np.random.randn(5),name = 'test')
print('s2:','\n',s2)
print('s1:','\n',s1.name, s2.name,type(s2.name))
# name为Series的一个参数,创建一个数组的 名称
# .name方法:输出数组的名称,输出格式为str,如果没用定义输出名称,输出为None
s3 = s2.rename('hehehe')
print(s3)
print(s3.name, s2.name)
# .rename()重命名一个数组的名称,并且新指向一个数组,原数组不变
Pandas数据结构Series:索引
位置下标 / 标签索引 / 切片索引 / 布尔型索引
# 位置下标,类似序列
s = pd.Series(np.random.rand(5))
print(s)
print(s[0],type(s[0]),s[0].dtype)
print(float(s[0]),type(float(s[0])))
#print(s[-1])
# 位置下标从0开始
# 输出结果为numpy.float格式,
# 可以通过float()函数转换为python float格式
# numpy.float与float占用字节不同
# s[-1]结果如何?#会报错,这个并不完全跟列表一样。
# 标签索引
# 方法类似下标索引,用[]表示,内写上index,注意index是字符串
s = pd.Series(np.random.rand(5), index = ['a','b','c','d','e'])
print(s)
print(s['a'],type(s['a']),s['a'].dtype)
# 如果需要选择多个标签的值,用[[]]来表示(相当于[]中包含一个列表)
# 多标签索引结果是新的数组
sci = s[['a','b','e']]
print(sci,type(sci))
# 切片索引
s1 = pd.Series(np.random.rand(5))
s2 = pd.Series(np.random.rand(5), index = ['a','b','c','d','e'])
print('s1:','\n',s1)
print('s2:','\n',s2)
print('下标:','\n',s1[1:4],'\n',s1[4])#下标
# 注意:用index(标签)做切片是末端包含
print('标签:','\n',s2['a':'c'],'\n',s2['c'])#标签
print(s2[0:3],s2[3])
print('-----')
# 下标索引做切片,和list写法一样
print(s2[:-1])
print(s2[::2])
# 布尔型索引
# 数组做判断之后,返回的是一个由布尔值组成的新的数组
# .isnull() / .notnull() 判断是否为空值 (None代表空值,NaN代表有问题的数值,两个都会识别为空值)
s = pd.Series(np.random.rand(3)*100)
s[4] = None # 添加一个空值 s[4] = None 也可以写成 s[4] = np.nan
print(s)
bs1 = s > 50
bs2 = s.isnull()#isnull:是否是空值
bs3 = s.notnull()#notnull:是否不是空值
print('bs1:','\n',bs1, type(bs1), bs1.dtype)
print('bs2:','\n',bs2, type(bs2), bs2.dtype)
print('bs3:','\n',bs3, type(bs3), bs3.dtype)
print('----------------------------------')
print(s[s > 50])
print(s[bs3])
# 布尔型索引方法:用[判断条件]表示,其中判断条件可以是 一个语句,或者是 一个布尔型数组!
Pandas数据结构Series:基本技巧
数据查看 / 重新索引 / 对齐 / 添加、修改、删除值
# 数据查看
import numpy as np
import pandas as pd
s = pd.Series(np.random.rand(50))
print(s.head(10))# .head()查看头部数据 # 默认查看5条
print(s.tail())# .tail()查看尾部数据 # 默认查看5条
# 重新索引reindex
# .reindex将会根据索引重新排序,如果当前索引不存在,则引入缺失值
s = pd.Series(np.random.rand(3), index = ['a','b','c'])
print(s)
s1 = s.reindex(['c','b','a','d'])# .reindex()中也是写列表
print(s1)# 这里'd'索引不存在,所以值为NaN
s2 = s.reindex(['c','b','a','d'], fill_value = 0)# fill_value参数:填充缺失值的值
print(s2)
# Series对齐
s1 = pd.Series(np.random.rand(3), index = ['Jack','Marry','Tom'])
s2 = pd.Series(np.random.rand(3), index = ['Wang','Jack','Marry'])
print(s1)
print(s2)
print(s1+s2)
# Series 和 ndarray 之间的主要区别是,Series 上的操作会根据标签自动对齐
# index顺序不会影响数值计算,以标签来计算
# ################空值和任何值计算结果扔为空值
# 删除:.drop
s = pd.Series(np.random.rand(5), index = list('ngjur'))
print('s:','\n',s)
s1 = s.drop('n')
s2 = s.drop(['g','j'],inplace=False)# drop 删除元素之后返回副本(inplace=False) inplace:默认为False,会生成一个副本
# s2 = s.drop(['g','j'],inplace=True)# drop 删除元素之后返回副本(inplace=False) inplace:默认为False,改为True后,父本会被改变,不会生成副本。
print('s1:','\n',s1)
print('s2:','\n',s2)
print('s:','\n',s)
# 添加
s1 = pd.Series(np.random.rand(5))
s2 = pd.Series(np.random.rand(5), index = list('ngjur'))
print(s1)
print(s2)
s1[5] = 100
s2['a'] = 100
print(s1)
print(s2)
print('-----')
# 直接通过下标索引/标签index添加值
s3 = s1.append(s2)
print(s3)
print(s1)
# 通过.append方法,直接添加一个数组
# .append方法生成一个新的数组,不改变之前的数组
# 修改
s = pd.Series(np.random.rand(3), index = ['a','b','c'])
print(s)
s['a'] = 100
s[['b','c']] = 200
print(s)
# 通过索引直接修改,类似序列
Pandas数据结构Dataframe:基本概念及创建
"二维数组"Dataframe:是一个表格型的数据结构,包含一组有序的列,其列的值类型可以是数值、字符串、布尔值等。
Dataframe中的数据以一个或多个二维块存放,不是列表、字典或一维数组结构。
# Dataframe 数据结构
# Dataframe是一个表格型的数据结构,“带有标签的二维数组”。
# Dataframe带有index(行标签)和columns(列标签)
data = {
'name':['Jack','Tom','Mary'],
'age':[18,19,20],
'gender':['m','m','w']}
frame = pd.DataFrame(data)
print(frame)
print(type(frame))
print(frame.index,'\n该数据类型为:',type(frame.index))
print(frame.columns,'\n该数据类型为:',type(frame.columns))
print(frame.values,'\n该数据类型为:',type(frame.values))
# 查看数据,数据类型为dataframe
# .index查看行标签
# .columns查看列标签
# .values查看值,数据类型为ndarray
# Dataframe 创建方法一:由数组/list组成的字典
# 创建方法:pandas.Dataframe()
# 由数组/list组成的字典 创建Dataframe,columns为字典key,index为默认数字标签
# 字典的值的长度必须保持一致!
data1 = {
'a':[1,2,3],
'b':[3,4,5],
'c':[5,6,7]}
data2 = {
'one':np.random.rand(3),
'two':np.random.rand(3)} # 这里如果尝试 'two':np.random.rand(4) 会怎么样?
print('data1:','\n',data1)
print('data2:','\n',data2)
df1 = pd.DataFrame(data1,index=['a','b','c'])
df2 = pd.DataFrame(data2)
print('df1:','\n',df1)
print('df2:','\n',df2)
# columns参数:可以重新指定列的顺序,格式为list,如果现有数据中没有该列(比如'd'),则产生NaN值
# 如果columns重新指定时候,列的数量可以少于原数据
df1 = pd.DataFrame(data1, columns = ['b','c','a','d'])
print('df1:','\n',df1)
df1 = pd.DataFrame(data1, columns = ['b','c'])
print('df1:','\n',df1)
df2 = pd.DataFrame(data2, index = ['f1','f2','f3']) # 这里如果尝试 index = ['f1','f2','f3','f4'] 会怎么样? 会报错
print('df2:','\n',df2)
# index参数:重新定义index,格式为list,长度必须保持一致
# Dataframe 创建方法二:由Series组成的字典
# 由Seris组成的字典 创建Dataframe,columns为字典key,index为Series的标签(如果Series没有指定标签,则是默认数字标签)
# Series可以长度不一样,生成的Dataframe会出现NaN值
data1 = {
'one':pd.Series(np.random.rand(2)),
'two':pd.Series(np.random.rand(3))} # 没有设置index的Series
data2 = {
'one':pd.Series(np.random.rand(2), index = ['a','b']),
'two':pd.Series(np.random.rand(3),index = ['a','b','c'])} # 设置了index的Series
print('data1:','\n',data1)
print('data2:','\n',data2)
df1 = pd.DataFrame(data1)
df2 = pd.DataFrame(data2)
print('df1:','\n',df1)
print('df2:','\n',df2)
# Dataframe 创建方法三:通过二维数组直接创建
# 通过二维数组直接创建Dataframe,得到一样形状的结果数据,如果不指定index和columns,两者均返回默认数字格式
# index和colunms指定长度与原数组保持一致
ar = np.random.rand(9).reshape(3,3)
print('ar:','\n',ar)
df1 = pd.DataFrame(ar)
df2 = pd.DataFrame(ar, index = ['a', 'b', 'c'], columns = ['one','two','three']) # 可以尝试一下index或columns长度不等于已有数组的情况
print('df1:','\n',df1)
print('df2:','\n',df2)
# Dataframe 创建方法四:由字典组成的列表
# 由字典组成的列表创建Dataframe,columns为字典的key,index不做指定则为默认数组标签
# colunms和index参数分别重新指定相应列及行标签
data = [{
'one': 1, 'two': 2}, {
'one': 5, 'two': 10, 'three': 20}]
print('data:','\n',data)
df1 = pd.DataFrame(data)
df2 = pd.DataFrame(data, index = ['a','b'])
df3 = pd.DataFrame(data, columns = ['one','two'])
print('df1:','\n',df1)
print('df2:','\n',df2)
print('df3:','\n',df3)
# Dataframe 创建方法五:由字典组成的字典
# 由字典组成的字典创建Dataframe,columns为字典的key,index为子字典的key
data = {
'Jack':{
'math':90,'english':89,'art':78},
'Marry':{
'math':82,'english':95,'art':92},
'Tom':{
'math':78,'english':67}}
df1 = pd.DataFrame(data)
print('df1:','\n',df1)
# columns参数可以增加和减少现有列,如出现新的列,值为NaN
# index在这里和之前不同,并不能改变原有index,如果指向新的标签,值为NaN (非常重要!)
df2 = pd.DataFrame(data, columns = ['Jack','Tom','Bob'])
df3 = pd.DataFrame(data, index = ['a','b','c'])
print('df2:','\n',df2)
print('df3:','\n',df3)
Pandas数据结构Dataframe:索引
Dataframe既有行索引也有列索引,可以被看做由Series组成的字典(共用一个索引)
选择列 / 选择行 / 切片 / 布尔判断
# 选择行与列
df = pd.DataFrame(np.random.rand(12).reshape(3,4)*100,
index = ['one','two','three'],
columns = ['a','b','c','d'])
print('df:','\n',df)
# 按照列名选择列,只选择一列输出Series,选择多列输出Dataframe
data1 = df['a']#选择单个列
data2 = df[['a','c']]#选择多个列
print('data1:','\n',data1,type(data1))
print('data2:','\n',data2,type(data2))
print('-----')
# 按照index选择行,只选择一行输出Series,选择多行输出Dataframe
data3 = df.loc['one']#选择单行
data4 = df.loc[['one','two']]#选择多行
print('data3:','\n',data3,type(data3))
print('data4:','\n',data4,type(data4))
# df[] - 选择列
# 一般用于选择列,也可以选择行
df = pd.DataFrame(np.random.rand(12).reshape(3,4)*100,
index = ['one','two','three'],
columns = ['a','b','c','d'])
print('df:','\n',df)
print('-----')
data1 = df['a']
data2 = df[['b','c']] # 尝试输入 data2 = df[['b','c','e']]
print('data1:','\n',data1)
print('data2:','\n',data2)
# df[]默认选择列,[]中写列名(所以一般数据colunms都会单独制定,不会用默认数字列名,以免和index冲突)
# 单选列为Series,print结果为Series格式
# 多选列为Dataframe,print结果为Dataframe格式
data3 = df[:1]
#data3 = df[0]
#data3 = df['one']
print('data3:','\n',data3,type(data3))
# df[]中为数字时,默认选择行,且只能进行切片的选择,不能单独选择(df[0])
# 输出结果为Dataframe,即便只选择一行
# df[]不能通过索引标签名来选择行(df['one'])
# 核心笔记:df[col]一般用于选择列,[]中写列名
# df.loc[] - 按index选择行
df1 = pd.DataFrame(np.random.rand(16).reshape(4,4)*100,
index = ['one','two','three','four'],
columns = ['a','b','c','d'])
df2 = pd.DataFrame(np.random.rand(16).reshape(4,4)*100,
columns = ['a','b','c','d'])
print('df1:','\n',df1)
print('df2:','\n',df2)
print('-----')
print('单标签索引:')
# 单个标签索引,返回Series
data1 = df1.loc['one']
data2 = df2.loc[[1]]
print('data1:','\n',data1)
print('data2:','\n',data2)
print('多标签索引:')
# 多个标签索引,如果标签不存在,则返回NaN
# 顺序可变
data3 = df1.loc[['two','three','four']]
data4 = df2.loc[[3,2,1]]
print('data3:','\n',data3)
print('data4:','\n',data4)
# 可以做切片对象
# 末端包含
data5 = df1.loc['one':'three']
data6 = df2.loc[1:3]
print('data5:','\n',data5)
print('data6:','\n',data6)
print('切片索引')
# 核心笔记:df.loc[label]主要针对index选择行,同时支持指定index,及默认数字index
# df.iloc[] - 按照整数位置(从轴的0到length-1)选择行
# 类似list的索引,其顺序就是dataframe的整数位置,从0开始计
df = pd.DataFrame(np.random.rand(16).reshape(4,4)*100,
index = ['one','two','three','four'],
columns = ['a','b','c','d'])
print('df:','\n',df)
print('------')
print('单位置索引:')
# 单位置索引
# 和loc索引不同,不能索引超出数据行数的整数位置
print('df.iloc[0]:','\n',df.iloc[0])
print('df.iloc[-1]:','\n',df.iloc[-1])
#print(df.iloc[4])
print('多位置索引:')
# 多位置索引
# 顺序可变
print('df.iloc[[0,2]]:','\n',df.iloc[[0,2]])
print('df.iloc[[3,2,1]]:','\n',df.iloc[[3,2,1]])
print('切片索引:')
# 切片索引
# 末端不包含
print('df.iloc[1:3]:','\n',df.iloc[1:3])
print('df.iloc[::2]:','\n',df.iloc[::2])
# 布尔型索引
# 和Series原理相同
df = pd.DataFrame(np.random.rand(16).reshape(4,4)*100,
index = ['one','two','three','four'],
columns = ['a','b','c','d'])
print('df:','\n',df)
print('------')
# 不做索引则会对数据每个值进行判断
# 索引结果保留 所有数据:True返回原数据,False返回值为NaN
b1 = df < 20
print('b1:','\n',b1,type(b1))
print('df[b1]:','\n',df[b1]) # 也可以书写为 df[df < 20]
# 单列做判断
# 索引结果保留 单列判断为True的行数据,包括其他列
b2 = df['a'] > 50
print('b2:','\n',b2,type(b2))
print('df[b2]:','\n',df[b2]) # 也可以书写为 df[df['a'] > 50]
# 多列做判断
# 索引结果保留 所有数据:True返回原数据,False返回值为NaN
b3 = df[['a','b']] > 50
print('b3:','\n',b3,type(b3))
print('df[b3]:','\n',df[b3]) # 也可以书写为 df[df[['a','b']] > 50]
# 多行做判断
# 索引结果保留 所有数据:True返回原数据,False返回值为NaN
b4 = df.loc[['one','three']] < 50
print('b4:','\n',b4,type(b4))
print('df[b4]:','\n',df[b4]) # 也可以书写为 df[df.loc[['one','three']] < 50]
# 多重索引:比如同时索引行和列
# 先选择列再选择行 —— 相当于对于一个数据,先筛选字段,再选择数据量
df = pd.DataFrame(np.random.rand(16).reshape(4,4)*100,
index = ['one','two','three','four'],
columns = ['a','b','c','d'])
print('df:','\n',df)
print('------')
print(df['a'].loc[['one','three']]) # 选择a列的one,three行
print('------')
print(df[['b','c','d']].iloc[::2]) # 选择b,c,d列的one,three行
print('------')
print(df[df['a'] < 50].iloc[:2]) # 选择满足判断索引的前两行数据
Pandas数据结构Dataframe:基本技巧
数据查看、转置 / 添加、修改、删除值 / 对齐 / 排序
import pandas as pd
import numpy as np
# 数据查看、转置
df = pd.DataFrame(np.random.rand(16).reshape(8,2)*100,columns = ['a','b'])
print('df:','\n',df)
print('前两个数据:','\n',df.head(2))# .head()查看头部数据 # 默认查看5条
print('后面五个数据:','\n',df.tail())# .tail()查看尾部数据 # 默认查看5条
# .T 转置
print('转置:','\n',df.T)
# 添加与修改
import numpy as np
import pandas as pd
df = pd.DataFrame(np.random.rand(16).reshape(4,4)*100,
columns = ['a','b','c','d'])
print('df:','\n',df)
# 新增列/行并赋值
df['e'] = 10
df.loc[4] = 20
print('df:','\n',df)
# 索引后直接修改值
df['e'] = 20
df[['a','c']] = 100
print('df:','\n',df)
df.iloc[::2] = 101
print('df.iloc[::2]:','\n',df)
# 删除 del / drop()
df = pd.DataFrame(np.random.rand(16).reshape(4,4)*100,
columns = ['a','b','c','d'])
print('df:','\n',df)
# del语句 - 删除列
del df['a']
print('df:','\n',df)
print('-----')
# drop()删除行,inplace=False → 删除后生成新的数据,不改变原数据
print('df.drop(0):','\n',df.drop(0))
print('df.drop([1,2]):','\n',df.drop([1,2]))
print('df:','\n',df)
print('-----')
# drop()删除列,需要加上axis = 1,inplace=False → 删除后生成新的数据,不改变原数据
print(df.drop(['d'], axis = 1))#inplace=True,删除后不会生成新的数据,直接改变原数据
print('df:','\n',df)
# 对齐
# DataFrame对象之间的数据自动按照列和索引(行标签)对齐
df1 = pd.DataFrame(np.random.randn(10, 4), columns=['A', 'B', 'C', 'D'])
df2 = pd.DataFrame(np.random.randn(7, 3), columns=['A', 'B', 'C'])
print('df1:','\n',df1)
print('df2:','\n',df2)
print('df1+df2:','\n',df1 + df2)
# 排序1 - 按值排序 .sort_values
# 同样适用于Series
df1 = pd.DataFrame(np.random.rand(16).reshape(4,4)*100,
columns = ['a','b','c','d'])
# ascending参数:设置升序降序,默认为True升序
# 单列排序
print('df1:','\n',df1)
print('df1.升序:','\n',df1.sort_values(['a'], ascending = True)) # 升序
print('df1.降序:','\n',df1.sort_values(['a'], ascending = False)) # 降序
print('------')
# 多列排序,按列顺序排序
df2 = pd.DataFrame({
'a':[1,1,1,1,2,2,2,2],
'b':list(range(8)),
'c':list(range(8,0,-1))})
print('df2:','\n',df2)
print('df2.多列排序:','\n',df2.sort_values(['a','c']))
# 排序2 - 索引排序 .sort_index
df1 = pd.DataFrame(np.random.rand(16).reshape(4,4)*100,
index = [5,4,3,2],
columns = ['a','b','c','d'])
df2 = pd.DataFrame(np.random.rand(16).reshape(4,4)*100,
index = ['h','s','x','g'],
columns = ['a','b','c','d'])
# 按照index排序
# 默认 ascending=True, inplace=False
print('df1:','\n',df1)
print('df1-索引排序:','\n',df1.sort_index())
print('df2:','\n',df2)
print('df2-索引排序:','\n',df2.sort_index())