学习Pandas(一)

Pandas是一个开放源码的Python库,它使用强大的数据结构提供高性能的数据操作。Pandas最初被作为金融数据分析工具而开发出来,因此,pandas为时间序列分析提供了很好的支持。 Pandas的名称来自于面板数据(panel data)和python数据分析(data analysis)。panel data是经济学中关于多维数据集的一个术语,在Pandas中也提供了panel的数据类型。

Pandas 数据结构

Series:一维数组,与Numpy中的一维array类似,二者与Python基本的数据结构List也很相近。Series如今能保存不同种数据类型,字符串、boolean值、数字等。
Time-Series:以时间为索引的Series。
DataFrame:二维的表格型数据结构,很多功能与R中的data.frame类似,可以将DataFrame理解为Series的容器。
Panel :三维数组,可以理解为DataFrame的容器。

series结构

也称Series序列,是Pandas常用数据结构之一,类似于一维数组,由一组数据值和一组标签组成,其中标签与数据值具有对应关系。

标签不必是唯一的,但必须是可哈希类型,该对象即支持基于整数的索引,也支持基于标签的索引,并提供了许多方法来执行涉及索引的操作。ndarray的统计方法已被覆盖,自动排除缺失的数据(目前表示为NaN)。
Series可以保存任何数据类型,比如整数、字符串、浮点数、Python对象等,它的标签默认为整数,从0开始依次递增,Series结构图:
在这里插入图片描述

import pandas as pd

一、数据结构Series创建

pd.Series(data=None, index=None, dtype=None, name=None, copy=False)
data:输入的数据,可以是列表、常量、ndarray数组等。如果是字典,则保持参数顺序。
index:索引值,必须是可散列的(不可变数据类型(str,bytes和数据类型)),并且与数据具有相同的长度,允许使用非唯一索引值。如果未提供,将默认为RangeIndex(0,1,2,...,n)
dtype:输出系列的数据类型,如果未指定,将从数据中推断
copy:表示对data进行拷贝,默认为False,仅影响Series和ndarray数组。

创建

1.列表、数组作为数据源创建Series

列表作为数据源创建Series


ar_list = [3,10,3,4,5]
print(type(ar_list))
#使用列表创建Series
s1 = pd.Series(ar_list)
print(s1)
print(type(s1))

输出:

在这里插入图片描述
数组作为数据源:

#数组作为数据源
np_rand = np.arange(1,6)
# 使用数组创建Series
s1 = pd.Series(np_rand)
s1

输出:
在这里插入图片描述

通过index和values属性取得对应的标签和值

#默认为Range Index(0,1,2,...n)
s1.index

输出:

RangeIndex(start=0, stop=5, step=1)

可以强制转化为列表输出

list(s1.index)

输出:

[0, 1, 2, 3, 4]

返回Series所有值,数据类型为ndarray:

#返回Series所有值,数据类型为ndarray
print(s1.values,type(s1.values))

输出:

[1 2 3 4 5] <class 'numpy.ndarray'>

通过索引取得对应的值,或者修改对应的值:s1[1]
输出:2

s1[2]= 50
s1

输出:

0     1
1     2
2    50
3     4
4     5
dtype: int32

Series不能通过-1索引:s1[-1]
报错:-1 is not in range

总结Series结构索引和列表结构索引的区别:
默认的索引RangeIndex,不能使用负值来表示从后往前找元素
获取不存在的索引值对应数据,会报错,但是可以赋值,相当于新增数据
可以新增不同类型索引的数据,新增后索引的类型会自动发生变化

不能索引s[-1],但可以新增s[-1]:

s1[-1]=20
print(s1)
print(s1.index)

输出:

 0     1
 1     2
 2    50
 3     4
 4     5
-1    20
dtype: int64  #类型由int32-->int64
Int64Index([0, 1, 2, 3, 4, -1], dtype='int64')  

新增不同类型索引的数据:

s1["a"] = 40
s1

输出:

0      1
1      2
2     50
3      4
4      5
-1    20
a     40
dtype: int64

2.字典作为数据源创建Series

d = {'a':1, 'b':2, 'c':3}
ser = pd.Series(data=d)
ser

输出:

a    1
b    2
c    3
dtype: int64

查看标签:

ser.index

输出:Index(['a', 'b', 'c'], dtype='object')
查看值:

ser.values

输出:array([1, 2, 3], dtype=int64)
查看某一标签对应的值:ser['a']
输出:1
修改值:

ser['s'] = 50
ser

输出:

a     1
b     2
c     3
s    50
dtype: int64

如果标签非数值型,可以用标签取数据,也可以用下标取数据:ser[1]
输出:2 (和ser[‘b’]获取的数据一样)
标签如果存在数值型的数据,就不能使用标签的下标获取值:

d = {'a':1,0:2,'c':3} #标签含有数值型
ser1 = pd.Series(data=d)
ser1
d = {'a':1,0:2,'c':3}
ser1 = pd.Series(data=d)  
ser1
d = {'a':1,0:2,'c':3}
ser1 = pd.Series(data=d)
ser1
a    1
0    2
c    3
dtype: int64

使用ser1[1]
报错:
在这里插入图片描述

index参数

索引值,必须是可散列的(不可变数据类型(str,bytes和数值类型)),并且与数据具有相同的长度,允许使用非唯一索引值。如果未提供,将默认为RangeIndex(0,1,2,…,n)

使用”显示索引“的方法定义索引标签:

data = np.array(['a','b','c','d'])
#自定义索引标签(即显式索引),需要和数据长度一致
s = pd.Series(data,index=[100,101,102,103])
s

输出:

100    a
101    b
102    c
103    d
dtype: object

从指定索引的字典构造序列:

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

输出:

a    1
b    2
c    3
dtype: int64

当传递的索引值未匹配对应的字典键时,使用NaN(非数字)填充

d = {'a':1, 'b':2, 'c':3}
ser = pd.Series(data=d, index=['x','b','z'])
ser

输出:

x    NaN
b    2.0
z    NaN
dtype: float64

通过匹配的索引值,改变创建Series数据的顺序

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

输出:

c    3
b    2
a    1
dtype: int64

name参数

我们可以给一个Series对象命名,也可以给一个Series数组中的索引列起一个名字,pandas为我们设计好了对象的属性,并设置了name属性值用来进行名字的设定。

dict_data1 = {
    "Beijing":2200,
    "Shanghai":2500,
    "shenzhen":1700
}
data1 = pd.Series(dict_data1)
data1

输出:

Beijing     2200
Shanghai    2500
shenzhen    1700
dtype: int64

命名:

data1 = pd.Series(dict_data1)
data1.name = "City_Data"
data1.index.name = "City_name"
print(data1)

输出:

City_name#'City_name'是索引的name
Beijing     2200
Shanghai    2500
shenzhen    1700
Name: City_Data, dtype: int64   #'City_Data'是data1的name

DataFrame类型

序列的名称,如果是DataFrame的一部分,还包括列名

如果用于形成数据帧,序列的名称将成为其索引或列名,每当使用解释器显示序列时,也会是用它。
使用Series创建dataFrame类型:

df = pd.DataFrame(data1)
print(df,type(df))
print("="*20)
#输出City_Data列的数据和类型
print(df['City_Data'])
print(type(df['City_Data']))

输出:

        City_Data
City_name           
Beijing         2200
Shanghai        2500
shenzhen        1700 <class 'pandas.core.frame.DataFrame'>
====================
City_name
Beijing     2200
Shanghai    2500
shenzhen    1700
Name: City_Data, dtype: int64
<class 'pandas.core.series.Series'>

copy参数

copy表示对data进行拷贝,默认为False,仅影响Series和ndarry数组
使用数组创建Series,改变改变Series标签为1的值:

#数组作为数据源
np_rand = np.arange(1,6)
s1 = pd.Series(np_rand)
s1[1] = 50
#输出Series对象s1
print("s1:\n",s1)
#输出数组对象为np_rand
print("np_rand:",np_rand)

输出:

s1:
 0     1
1    50
2     3
3     4
4     5
dtype: int32
np_rand: [ 1 50  3  4  5]#改变了

当源数据非Series和ndarray类型时,将列表作为数据源,改变Series标签为1的值:

my_list = [1,2,3,4,5,6]
s2 = pd.Series(my_list)
s2[1] = 50
print("s2:",s2)
print("my_list:",my_list)

输出:

s2: 0     1
1    50
2     3
3     4
4     5
5     6
dtype: int64
my_list: [1, 2, 3, 4, 5, 6]#未改变

二、Series的索引/切片

1.下标索引

位置索引和标签索引刚好一致,会使用标签索引:

s = pd.Series(np.random.rand(5))
print(s)
print(s[3], type(s[3]), s[3].dtype)

输出:

0    0.681156
1    0.209843
2    0.617324
3    0.374747
4    0.968413
dtype: float64
0.37474695269005986 <class 'numpy.float64'> float64

使用负值时,实际上并不存在负数的标签索引

当索引对象为object类型时,既可以使用标签索引,也可以使用位置索引

Series类似于固定大小的dict,把Index中的标签索引当作key,而把Series中的序列值当作value,然后通过index索引标签来访问或修改元素值。

使用索标签访问单个元素值:

s = pd.Series(np.random.rand(5), index=list("abcde"))
print(s["b"],type(s["b"]), s["b"].dtype)

输出:

0.9686922887415305 <class 'numpy.float64'> float64

使用索引标签访问多个元素值:

s = pd.Series([6,7,8,9,10],index = ['a','b','c','d','e'])
print(s)
#注意需要选择多个标签的值,用[[]]来表示(相当于[]中包含一个列表)
print(s[['a','c','d']])

输出:

a     6
b     7
c     8
d     9
e    10
dtype: int64
a    6
c    8
d    9
dtype: int64

多标签会创建一个新的数组:

s1 = s[['b','a','e']]
s1["b"] = 2
print("s1:\n",s1)
print("s源数据:\n",s)

输出:

s1:
 b     2
a     6
e    10
dtype: int64
s源数据:
 a     6
b     7
c     8
d     9
e    10
dtype: int64

3.切片

Series使用标签切片运算和普通的Python切片运算不同:
Series使用标签切片时,其末端是包含的。
Series使用Python切片运算即使用位置数值切片,其末端不包含。

通过下标切片的方式访问Series序列中的数据:

s = pd.Series(np.random.rand(10))
s[1:5]

输出:

1    0.023120
2    0.281411
3    0.883626
4    0.477901
dtype: float64

位置索引和标签索引刚好一致,使用切片时,如果是数值会认为是python切片运算,不包含末端

s = pd.Series([1,2,3,4,5],index=['a','b','c','d','e'])
print(s)
print(s[1:4])

输出:

a    1
b    2
c    3
d    4
e    5
dtype: int64
b    2
c    3
d    4
dtype: int64

如果想要获取最后三个元素,可以使用下面方式:

s = pd.Series([1,2,3,4,5], index = ['a','b','c','d','e'])
print(s[-3:])

输出:

c    3
d    4
e    5
dtype: int64

通过标签切片的方式访问Series序列中的数据:

s1 = pd.Series([6,7,8,9,10],index = ['a','b','c','d','e'])
s1["b":"d"]

末端包含:

b    7
c    8
d    9
dtype: int64
s1["c":"c"]

输出:

c    8
dtype: int64

注意:
当index为数值类型的时候:
进行索引的时候,相当于使用的是名称索引(使用位置索引会报错)
进行切片的时候,相当于使用的是位置切片

三、Series数据结构 基本技巧

1.查看前几条和后几条数据

s = pd.Series(np.random.rand(15))
s

输出:

0     0.609290
1     0.162900
2     0.751565
3     0.886997
4     0.263947
5     0.984391
6     0.829509
7     0.095259
8     0.966457
9     0.447003
10    0.746117
11    0.587411
12    0.350907
13    0.849317
14    0.016918
dtype: float64

s.head()的使用

print(s.head())#默认查看前5条数据
print(s.head(1))#默认查看前1条数据

输出:

print(s.head())#默认查看前5条数据
print(s.head(1))#默认查看前1条数据
print(s.head())#默认查看前5条数据
print(s.head(1))#默认查看前1条数据
0    0.609290
1    0.162900
2    0.751565
3    0.886997
4    0.263947
dtype: float64
0    0.60929
dtype: float64

s.tail()的使用:

print(s.tail())# 默认查看后5条数据

输出:

10    0.746117
11    0.587411
12    0.350907
13    0.849317
14    0.016918
dtype: float64

2.重新索引 reindex

使用可选填充逻辑,使Series符合新索引
将NaN放在上一个索引中没有值得位置,除非新索引等同于当前索引,并且生成新对象。

s = pd.Series(np.random.rand(5),index=list("abcde"))
print("+++++++++++s+++++++++")
print(s)
#新索引在上一个索引中不存在,生成新对象时,对应的值,设置为NaN
s1 = s.reindex(list("cde12"))
print("+++++++++++s+++++++++")
print(s1)

输出:

+++++++++++s+++++++++
a    0.790252
b    0.490827
c    0.439055
d    0.425065
e    0.597086
dtype: float64
+++++++++++s+++++++++
c    0.439055
d    0.425065
e    0.597086
1         NaN
2         NaN
dtype: float64

设置填充值:

s2 = s.reindex(list("cde12"), fill_value=0)
print(s2)

输出:

c    0.439055
d    0.425065
e    0.597086
1    0.000000
2    0.000000
dtype: float64

3.对齐运算

是数据清洗的重要过程,可以按索引对齐进行计算,如果没对齐得位置则补NaN,最后也可以填充NaN

s1 = pd.Series(np.random.rand(3),index=["kelly","Anne","T-C"])
s2 = pd.Series(np.random.rand(3), index=["Anne", "Kelly", "Lily"])
print("========s1========")
print(s1)
print("========s2========")
print(s2)

print("========s1+s2========")
print(s1+s2)

输出:

========s1========
kelly    0.002373
Anne     0.070553
T-C      0.756331
dtype: float64
========s2========
Anne     0.950720
Kelly    0.240003
Lily     0.607813
dtype: float64
========s1+s2========
Anne     1.021272
Kelly         NaN
Lily          NaN
T-C           NaN
kelly         NaN
dtype: float64

4.删除和添加

删除:

返回删除后的值,原值不改变,默认Inplace=False:

s = pd.Series(np.random.rand(5),index=list("abcde"))
print(s)
s1 = s.drop("a") #返回删除后的值,原值不改变,默认Inplace=False
print(s1)
print(s)

输出:

a    0.325819
b    0.338770
c    0.580162
d    0.377663
e    0.248908
dtype: float64
b    0.338770
c    0.580162
d    0.377663
e    0.248908
dtype: float64
a    0.325819
b    0.338770
c    0.580162
d    0.377663
e    0.248908
dtype: float64

将inplace置为True

s = pd.Series(np.random.rand(5),index=list("abcde"))

s1 = s.drop("a",inplace=True) #原值发生变化,返回None
print(s1)
print("========")
print(s)

输出:

None
========
b    0.994583
c    0.877292
d    0.756831
e    0.670073
dtype: float64
添加
s1 = pd.Series(np.random.rand(5),index=list("abcde"))
print(s1)

s1["s"] = 100
print(s1)

输出:

a    0.713630
b    0.142949
c    0.285360
d    0.422420
e    0.117981
dtype: float64
a      0.713630
b      0.142949
c      0.285360
d      0.422420
e      0.117981
s    100.000000
dtype: float64
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值