python数据分析 | Pandas全面介绍及使用(1)

1 Pandas 的介绍和安装

(1)为什么会有Pandas?
Pandas支持大部分Numpy语言风格,尤其是数组函数与广播机制的各种数据处理。但是Numpy更适合处理同质型的数据。而Pandas的设计就是用来处理表格型或异质型数据的,高效的清洗、处理数据。
(2)Pandas是什么?
Pandas是基于Numpy的一种工具,提供了高性能矩阵的运算,该工具是为了解决数据分析任务而创建的。也是贯穿整个Python数据分析非常核心的工具。
(3)Pandas涉及内容
在这里插入图片描述(4)Pandas安装
直接在dos命令行中输入pip install pandas

2 Pandas中Series的数据结构介绍

2.1 Series的介绍

Series是一种一维的数组型对象,它包含了一个值序列(values),并且包含了数据标签,称为索引(index),本质相当于一列数据。

2.2 Series的创建

语法:pd.Series(data=None,index=None,dtype=None,name=None,copy=False)

  • data:创建数组的数据,可为array-like, dict, or scalar value
  • index:指定索引
  • dtype:数组数据类型
  • name:数组名称
  • copy:是否拷贝
  • 注意:data可为iterable, dict, or scalar value
"""data为iterable"""
s1 = pd.Series([1,2,3,4],index=['a','b','c','d'],name='example')
print(s1)

"""注意1:pandas里面索引是可重复的"""
s2 = pd.Series([1,2,3,4,5],index=list("aacde"))
print(s2)  

"""注意2:索引的个数与data的个数是否要一致?index与values的个数必须一致"""
# s3 = pd.Series([1,2,3,4,5],index=list("aabcde"))
# print(s3) # 报错
"""data为字典,key对应索引,value对应值"""
dic1 = {"name":"steven","age":18,"gender":"male"}
s4 = pd.Series(dic1)
print(s4)

# 构建索引列表
dic2 = {"name":"steven","age":18,"gender":"male"}
index_li = ["class","name","gender"]
s5 = pd.Series(dic2,index=index_li)  # 以index指定的索引列表为主  class 在dic2 中没有,以nan形式填充
print(s5)
"""data为向量scalar"""
s6 = pd.Series(np.random.randint(1,10,size=5),dtype="float")
print(s6)  # 查看类型

除此之外,Pandas可以使用Numpy的数组函数

  • s.dtype :查看数据类型
  • s.astype():修改数据类型
  • s.head(n) :预览数据前5条
  • s.tail(n) :预览数据后5条

但是如果需要显示所有数据,则需以下代码。但并不建议使用

`#显示所有列
pd.set_option('display.max_columns', None)

#显示所有行
pd.set_option('display.max_rows', None)

#设置value的显示长度为100,默认为50
pd.set_option('max_colwidth',100)

2.3 Series的索引与切片

2.3.1 Series的索引与值

  • s.index : 查看索引
  • s.values:查看值序列
  • s.reset_index(drop=False):重置索引
  • drop :是否删除原索引 默认为否
  • 注意 :索引对象是不可变的,所以不能单个修改索引
s1 = pd.Series(np.arange(5))
s2 = pd.Series(['a','b','c'],index=['A','B','C'])
print(s1,s2)
print(s1.index,type(s1.index),s2.index,type(s2.index))
print(s1.values,type(s1.values),s2.values,type(s2.values))
# 获取索引A  注意:不是s2["A"] 这样是取值的
print(s1.index[1])
print(s2.index[1])
# print(s2.index['A'])  # 报错
# 是否可以修改单独的索引?
# s2.index[1] = "D"      # 报错:注意:索引对象是不可变的,为了更安全

2.3.2 Series的索引与切片

  • s[‘标签’]: 通过标签
  • s[‘索引’] :通过索引
  • s.loc[标签] : 通过标签
  • s.iloc[索引]:通过索引
s1 = pd.Series(np.arange(1,6),index=list("abbde"))
print(s1)

# 取2
print(s1["b"],'\n','----------------')  # 通过标签
print(s1[1],'\n','----------------')    # 通过索引
print(s1.loc["b"],'\n','----------------')  # 通过标签
print(s1.iloc[1],'\n','----------------')  # 通过索引

# 查看 "a","d"
print(s1[["a","d"]],'\n','----------------')   # 通过标签
print(s1[[0,3]],'\n','----------------')     # 通过索引

# 取大于3的值  布尔索引
print(s1[s1>3],'\n','----------------')

# pandas 会根据数据类型 自动的处理缺失数据
data = ["a","b",None]
print(pd.Series(data),'\n','----------------')   # object

data = [1,2,None]
print(pd.Series(data),'\n','----------------')   # np.nan 浮点类型  float64

2.4 Series 的运算

  • 共同索引对应为运算,其它填充NaN
  • 没有共同索引时,则全部为NaN
"""共同索引对应为运算,其它填充NaN"""
s1 = pd.Series(np.arange(10,20),index=range(10))
s2 = pd.Series(np.arange(20,25),index=range(5))
print(s1,'\n','----------------')
print(s2,'\n','----------------')
print(s1+s2,'\n','----------------')

"""没有共同索引时,则全部为NaN"""
s3 = pd.Series(np.arange(5),index=range(5))
s4 = pd.Series(np.arange(5,10),index=range(5,10))
print(s3,'\n','----------------')
print(s4,'\n','----------------')
print(s3+s4,'\n','----------------')

3 Pandas中DataFrame的数据结构介绍

3.1 DataFrame介绍

DataFrame表示的是矩阵的数据表,它包含已排序的列集合,每一列可以是不同的值类型(数值,字符串,布尔值)。在DataFrame中,数据被存储为一个以上的二维块。
在这里插入图片描述

3.2 DataFrame创建

pd.DataFrame(data=None,index=None,columns=None,dtype=None,copy=False)

  • data:创建数组的数据,可为ndarray, dict
  • index:指定索引
  • dtype:数组数据类型
  • copy:是否拷贝
d1 = pd.DataFrame(np.random.randint(1,100,size=(3,3)))
print(d1,'\n','-------------------------------------------------')

"""
行索引  index    0轴 axis=0
列索引  columns  1轴 axis=1
值      values
"""
print(d1.index,'\n','-------------------------------------------------')     # RangeIndex
print(d1.columns,'\n','-------------------------------------------------')   # RangeIndex
print(d1.values,'\n','-------------------------------------------------')    # ndarray的二维数组

# 指定index 为["amy","mia","steven"]
# 指定columns 为["java","python","R"]
d2 = pd.DataFrame(np.random.randint(1,100,size=(3,3)),index=["amy","mia","steven"],columns=["java","python","R"])
print(d2,'\n','-------------------------------------------------')    

"""
字典形式的data(同Seires)
- key值为列索引
- value为值
- 行索引 不指定就为默认的
"""
data = {
    "name":["amy","mia","steven"],
    "lesson":["java","python","R"]
}
d3 = pd.DataFrame(data)
print(d3,'\n','-------------------------------------------------') 

# 指定一下列索引
d4 = pd.DataFrame(data,columns=["lesson","name"])
print(d4,'\n','-------------------------------------------------') 

# 以我们指定的columns为主
d5 = pd.DataFrame(data,columns=["lesson"])
print(d5,'\n','-------------------------------------------------') 

# 以我们指定的columns为主  指定的 多于 data的key值时,则会填充nan
d6 = pd.DataFrame(data,columns=["lesson","name","age"])  # age 不存在,填充为nan
print(d6,'\n','-------------------------------------------------') 

# 字典数据结构不一致的 也会补齐为nan
data1 = [
    {"name":"amy","age":18,"gender":1},
    {"name":"jun","age":20},
    {"name":"hy","gender":1}
]
d7 = pd.DataFrame(data1)
print(d7,'\n','-------------------------------------------------') 
"""
重置索引:
除了创建时可以指定,我们创建后还可以通过df.reindex()进行重置索引
语法:df.reindex(index=None, columns=None, axis=None,fill_value=nan)
"""

df = pd.DataFrame(np.arange(9).reshape(3,3),index=list("abc"),columns=list("ABC"))
print(df,'\n','-------------------------------------------------')

# 重置行索引
df1 = df.reindex(index=[1,2,3])  # 如果重置的索引 与 df中指定的index 无关系 则全部填充nan
print(df1,'\n','-------------------------------------------------')

df2 = df.reindex(index=["b","c","a"])  # 如果重置索引与df指定的索引 完全一致 但是乱序的话 根据重置索引变动
print(df2,'\n','-------------------------------------------------')

df3 = df.reindex(index=["b","c","a","d"])  # 如果重置索引 比 df指定的索引 多 则多出的部分填充nan
print(df3,'\n','-------------------------------------------------')


# 填充列索引
df4 = df.reindex(columns=list("BCA"))  # 跟行索引一样的本质一样,有就排序,没有就填充nan
print(df4,'\n','-------------------------------------------------')

# 同时重置
df5 = df.reindex(index=list("bca"),columns=list("CBA"))
print(df5,'\n','-------------------------------------------------')

3.3 DataFrame基础操作

  • df.shape :查看数组形状,返回值为元组
  • df.dtypes :查看列数据类型
  • df.ndim :数据维度,返回为整数
  • df.index :行索引
  • df.columns :列索引
  • df.values :值
  • d.head(n) :显示头部几行,默认前5行
  • d.tail(n) :显示末尾几行,默认后5行
  • d.info() :相关信息概述
data = [
    {"name":"amy","age":18,"tel":10086},
    {"name":"bob","age":18},
    {"name":"james","tel":10086},
    {"name":"zs","tel":10086},
    {"name":"james","tel":10086},
    {"name":"ls","tel":10086},
]


d1 = pd.DataFrame(data)
print(d1,'\n','-------------------------------------------------')
print(d1.shape,'\n','-------------------------------------------------')    # 查看数组形状 (6,3)  六行三列  二维的
print(d1.ndim,'\n','-------------------------------------------------')     # 查看数组维度 df为二维的
print(d1.dtypes,'\n','-------------------------------------------------')   # 查看列的数据类型 注意:每列的类型可以不一致 体现pandas更加灵活
print(d1.head(),'\n','-------------------------------------------------')   # 显示前几行 默认为5
print(d1.tail(),'\n','-------------------------------------------------')   # 显示末尾几行 默认为5
print(d1.info(),'\n','-------------------------------------------------')   # 描述信息概要   Non-Null Count:非NAN数据的次数

3.4 DataFrame的增删改查

3.4.1 DataFrame的查

  • 直接使用索引与标签
    在这里插入图片描述
  • 使用loc及iloc查询数据
    ·df.loc[] 通过轴标签选择数据
    ·df.iloc[] 通过整数索引选择数据
    在这里插入图片描述
"""使用索引查询数据"""
data = [
    {"name":"amy","age":18,"tel":10086},
    {"name":"bob","age":18},
    {"name":"james","tel":10086},
    {"name":"zs","tel":10086},
    {"name":"james","tel":10086},
    {"name":"ls","tel":10086},
]

d1 = pd.DataFrame(data,index=list("abcdef"))
print(d1,'\n','-------------------------------------------------')
"""
行索引
"""
# 取前两行
print(d1[:2],'\n','-------------------------------------------------')     # 索引
print(d1[:"b"],'\n','-------------------------------------------------')   # 标签  []
# d1[["a","b"]]   # 报错 这种写法默认为 列索引,所以去列索引中找 没找着,则报错
# d1["a"]         # 报错  这种写法默认为 列索引

"""
列索引
"""
# 取 name 这列  字典的本质
print(d1["name"],'\n','-------------------------------------------------')        # 取出来单列,会变为Series类型
print(d1.name,'\n','-------------------------------------------------')
print(type(d1["name"]),'\n','-------------------------------------------------')  # DataFrame其实是Series容器

# 取 name,tel
print(d1[["name","tel"]],'\n','-------------------------------------------------')    # 取两列,取多列仍然时DataFrame
print(type(d1[["name","tel"]]),'\n','-------------------------------------------------')

# 取前两行的 name
print(d1[:2]["name"],'\n','-------------------------------------------------')

# 布尔索引 取出 name 不为james
print(d1[d1["name"]!="james"],'\n','-------------------------------------------------')
"""使用loc及iloc查询数据"""
idx = ["PHP","JAVA","Python","GO"]
col = ["one","two","three","four"]
d2 = pd.DataFrame(np.arange(16).reshape(4,4),index=idx,columns=col)
print(d2,'\n','-------------------------------------------------')
"""
df.loc[行,列]
取单
"""
# 取 Python 这行   
print(d2.loc["Python",:],'\n','-------------------------------------------------')

# 取 three 这列
print(d2.loc[:,"three"],'\n','-------------------------------------------------')

"""
df.loc[行,列]
取多行
"""
# 取 PHP 与 GO 这两行
print(d2.loc[["PHP","GO"],:],'\n','-------------------------------------------------')

# 取 PHP 到 GO 这四行
print(d2.loc["PHP":"GO",:],'\n','-------------------------------------------------')


# 取 one four 两列
print(d2.loc[:,["one","four"]],'\n','-------------------------------------------------')

# 取连续行 java~go 
print(d2.loc["JAVA":"GO",:],'\n','-------------------------------------------------')   # 标签索引可以切片 双闭合
"""
索引位置
df.iloc[行,列]
"""
# 取 Python 这行  
print(d2.iloc[2,:],'\n','-------------------------------------------------')

# 取 three 这列
print(d2.iloc[:,2],'\n','-------------------------------------------------')

# 去连续行 java~go
print(d2.iloc[1::,:],'\n','-------------------------------------------------')     # 左闭右开

# 取出 one two three数据 并且 筛选出 two列 大于3的
print(d2.loc[:,"one":"three"][d2.two>3],'\n','-------------------------------------------------')
idx = ["PHP","GO","Python","GO"]
col = ["one","two","three","four"]
d3 = pd.DataFrame(np.arange(16).reshape(4,4),index=idx,columns=list("1234"))
print(d3,'\n','--------------------------------------------')
# print(d3.loc["PHP":"GO",:])   # 报错
"""
注意:如果 出现了重复索引 然后切片时出现歧义则会报错
注意:如果列索引 为 1,2,3,4这种就不要使用 d3.1 访问会报错。
"""
### 3.4.2 DataFrame的改
修改数据主要遵循以下两点:
- 查询数据
- 再赋值

注意:Pandas中可以直接赋值np.nan,且赋值当前列数据会自动转为浮点类型。而不是整个数组都转,这主要是因为Pandas数据可以是异质性。
idx = ["PHP","GO","Python","GO"]
col = ["one","two","three","four"]
d4 = pd.DataFrame(np.arange(16).reshape(4,4),index=idx,columns=col)
print(d4,'\n','--------------------------------------------')

# 修改php 整行数据为 8  注意:修改的是原数据
d4.loc["PHP",:] = 8
print(d4,'\n','--------------------------------------------')

# 修改two 整列数据为 10  注意:修改的是原数据
d4.loc[:,"two"] = 10
print(d4,'\n','--------------------------------------------')

# 修改对应python和hree的10改为80
d4.loc["Python","three"] = 80
print(d4,'\n','--------------------------------------------')

# 可以直接赋值为np.nan吗?
d4.loc["Python","three"] = np.nan
print(d4,'\n','--------------------------------------------')     # 注意:pandas可以自动转为float

3.4.3 DataFrame的增

  • 新增列:df[“新的列标签”] = 值
    注意:添加列,则新添加的值的长度必须与其它列的长度保持一致,否则会报错。
  • 插入列:如果需要在数据中插入列,则使用 df.insert(loc, column, value)
    • loc 为插入列的位置
    • column 为插入列的标签
    • value 为插入列的值
  • 添加行:df.loc[“新的行标签”,:] = 值
  • 除此之外,我们还可以通过 df.append(df2) 方法添加行,但类似于数组与数组的堆叠拼接。所以df2的列索引必须同df一致。
"""新增列"""
idx = ["PHP","JAVA","Python","GO"]
col = ["one","two","three","four"]
d5 = pd.DataFrame(np.arange(16).reshape(4,4),index=idx,columns=col)
print(d5,'\n','--------------------------------------------')

# 添加five列 全为10
d5["five"] = 10   
print(d5,'\n','--------------------------------------------')

# 重复索引会覆盖原有的信息
d5["five"] = [1,2,3,4]
print(d5,'\n','--------------------------------------------')

# 添加列,则需要保证数组的长度与该列的长度一致
# d5["five"] = [1,2,3]    # 报错
# print(d5,'\n','--------------------------------------------')

"""插入列"""
# 在第0列前 插入"six"这列 
d5.insert(0,"six",[4,5,76,8])
print(d5,'\n','--------------------------------------------')

"""添加行"""
d5.loc["C++",:] = np.arange(6)
print(d5,'\n','--------------------------------------------')

"""叠加"""
d6 = pd.DataFrame(np.arange(6).reshape(1,6),index=["C"],columns=d5.columns)
d5= d5.append(d6)   # 添加行 注意:d6与d5的列索引一致
print(d5,'\n','--------------------------------------------')

3.4.4 DataFrame的删

  • 法1:del df[“列标签”]
  • 法2:df.drop(axis=0,index=None,columns=None, inplace=False)
d7 = pd.DataFrame(np.arange(9).reshape(3,3),index=list("abc"),columns=list("ABC"))
print(d7,'\n','--------------------------------------------')

# del删除数据
del d7["C"]     # 获取到"C"列 删除这列
print(d7,'\n','--------------------------------------------')

# drop 删除数据
d8 = d7.drop(columns="A")  # 删除"A"列  
print(d8,'\n','--------------------------------------------')

# 删除 "a","c"两行
d9 = d7.drop(index=["a","c"])  
print(d9,'\n','--------------------------------------------')

# 指定轴来控制   行与列
d10 = d7.drop("b",axis=0)
print(d10,'\n','--------------------------------------------')
d11= d7.drop("A",axis=1)
print(d11,'\n','--------------------------------------------')

3.5 DataFrame的合并

3.5.1 pd.concat

语法:df = pd.concat(objs, axis = 0, ignore_index = False, join = "outer
(1)concat是”contatenate"的缩写,指的是多表之间的“拼接”。事实上“拼接”和“合并”还是有区别的,拼接一般是上下,合并时左右。
(2)参数解释:

  • objs: 指的是要合并的dataframe(们)。可以是一个列表[df1,df2,…]也可以是一个集合(df1,df2,…)。
  • axis:指的是拼接的方向。axis = 0指的是拼接行(向下拼接),axis = 1指的是拼接列(向右拼接)。
  • ignore_index: 指的是拼接后是否忽视原df各自的索引。比如,假如我们按行拼接,原来df1中有五条数据,索引是0,1,2,3,4。原来的df2中也有五条数据,索引也是0,1,2,3,4。如果我们在合并时,将ignoreindex的值设为False,那么拼接后df的索引就是0,1,2,3,4,0,1,2,3,4。那么如果将ignore_index的值设为True, 那么拼接后df的索引就是0,1,2,3,4,5,6,7…
  • join:表示“如何拼接”。由于两表中的信息可能是不同的,所以要设置这个参数以表明拼接方式。其中,outer表示取并集,inner表示取交集。
    举例来看一下吧
df1 = pd.DataFrame(np.arange(12).reshape(4,3),index=range(0,4),columns=list('abc'))
df2 = pd.DataFrame(np.arange(12).reshape(4,3),index=range(0,4),columns=list('def'))
print(df1,'\n','--------------------------------------------')
print(df2,'\n','--------------------------------------------')

# df3 = pd.concat([df1,df2],axis=0)
# df3
df4 = pd.concat([df1,df2],axis=1,ignore_index=False)
df4

3.5.2 df.append

语法:df = df1.append(df2)
append可以视作axis=0的,简便版的concat。也就是说,它只支持行拼接,同时比concat简便一些。

  • 这里要注意和concat的用法区别。concat是pd的属性,所以调用的时候应该是pd.concat((df1,df2)),而append是对df的方法,所以调用的时候是df1.append(df2)
df1 = pd.DataFrame(np.arange(12).reshape(4,3),index=range(0,4),columns=list('abc'))
df2 = pd.DataFrame(np.arange(12).reshape(4,3),index=range(0,4),columns=list('def'))
print(df1,'\n','--------------------------------------------')
print(df2,'\n','--------------------------------------------')

df3 = df1.append(df2)
df3

3.5.3 pd.merge

语法:df = pd.merge(left, right, how = "inner",on = "None")
与concat(拼接)不同,merge才是真正意义上的”合并“。

  • 拼接和合并的区别在于,拼接只是简单地”堆“在一起,而合并则是基于某一个”主键“将两个表”合“在一起。事实上merge也有很多参数,这里只列了最常用的。其中:
  • 参数解释:
    (1)left: 左表。也就是第一个df。
    (2)right:右表。也就是第二个df。
    (3)how: 和concat里面的"join"类似,表示“如何合并两表。除了”inner“和”outer“以外,merge中还有”left"(基于左表进行合并)和“right”(基于右表进行合并)。具体地:1)left: 只使用左表的键。2)right:只使用右表的键。3)inner: 使用左右表键的交集。4)outer:使用左右表键的并集。
    (4)on: 表示按照哪一个键来进行合并
df1= pd.DataFrame(np.arange(12).reshape(4,3),index=range(0,4),columns=list('abc'))
df2 = pd.DataFrame(np.arange(12).reshape(4,3),index=range(0,4),columns=list('def'))
print(df1,'\n','--------------------------------------------')
print(df2,'\n','--------------------------------------------')

df3 = pd.merge(df1,df2,how='outer',left_index=True,right_index=True)
df3

3.5.4 df.join

语法:df = left.join(right,on = "key", how = "left")

  • 类似于append之于concat,join也可以被理解为merge的一个简便并且特殊的方法。join也可以设置参数"how",只不过这里默认值不同。Merge中,how的默认值是”inner“,join中的默认值为”left"。
df1= pd.DataFrame(np.arange(12).reshape(4,3),index=range(0,4),columns=list('abc'))
df2 = pd.DataFrame(np.arange(12).reshape(4,3),index=range(0,4),columns=list('def'))
print(df1,'\n','--------------------------------------------')
print(df2,'\n','--------------------------------------------')

df3 = df1.join(df2,how='right')
df3
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值