1pandas数据结构介绍
pandas有两大常用的工具数据结构:Series和DataFrame。
1.1Series
Series是一种一维的数组型对象,它包含了一个值序列,并且包含了数据标签,称为索引(index)。最简单的序列可以仅仅由一个数组形成:
import pandas as pd
obj = pd.Series([4,3,5,6])
print(obj)
--------------------------
0 4
1 3
2 5
3 6
dtype: int64
从中我们可以看到索引在左边,值在右边。由于我们不为数组指定索引,默认生成的索引是从0带N-1(N是数组的长度)。我们可以通过values属性和index属性分别获得Series对象的值和索引:
print(obj.values) #[4 3 5 6]
print(obj.index) #RangeIndex(start=0, stop=4, step=1)
通常需要一个索引序列,用标签标识每个数据点:
obj = pd.Series([4,7,-5,3],index = ['d','b','a','c'])
print(obj)
-----------------------------------------------------
d 4
b 7
a -5
c 3
dtype: int64
print(obj.index) #Index(['d', 'b', 'a', 'c'], dtype='object')
我们可以在从数据中选择数据的时候使用标签来进行索引:
print(obj['a']) #-5
print(obj['d']) #4
print(obj[['c','a','b']])
-------------------------
c 3
a -5
b 7
dtype: int64
上面的例子中,[‘c’,‘a’,‘d’]包含的不是数字而是字符串,作为索引列表。
使用NumPy的函数或NumPy风格的操作,比如使用布尔值数组进行过滤,与标量相乘,或是应用数学函数,这些操作将保存索引值连接:
print(obj[obj > 0])
-------------------
d 4
b 7
c 3
dtype: int64
print(obj * 2)
-------------------
d 8
b 14
a -10
c 6
dtype: int64
print(np.exp(obj))
-------------------
d 54.598150
b 1096.633158
a 0.006738
c 20.085537
dtype: float64
从另一个角度考虑Series,可以认为它是一个长度固定且有序的字典,因为它将索引值和数据值按位置配对:
print('b' in obj) #True
print('e' in obj) #False
我们可以使用字典生成一个Series:
sdata = {'Ohio':35000,'Texas':71000,'Oregon':16000,'Utah':5000}
obj = pd.Series(sdata)
print(obj)
----------------------
Ohio 35000
Texas 71000
Oregon 16000
Utah 5000
dtype: int64
当我们把字典传递给Series构造函数时,产生的Series的索引将是排序好的字典键。我们可以将字典键按照我们所想要的顺序传递给构造函数:
sdata = {'Ohio':35000,'Texas':71000,'Oregon':16000,'Utah':5000}
states = ['California','Ohio','Oregon','Texas']
obj = pd.Series(sdata,index = states)
print(obj)
-------------------------------------
California NaN
Ohio 35000.0
Oregon 16000.0
Texas 71000.0
dtype: float64
上面的例子中,sdata中的三个值被放置在正确的位置,但是因为’California’没有出现在sdata的键中,它对应的值是NaN(not a number),这是pandas中标记缺失值或NA值的方式。
pandas中使用isnull和notnull函数来检查缺失数据:
print(pd.isnull(obj))
---------------------
California True
Ohio False
Oregon False
Texas False
dtype: bool
print(pd.notnull(obj))
---------------------
California False
Ohio True
Oregon True
Texas True
dtype: bool
isnull和notnull也是Series的实例方法:
print(obj.isnull())
-------------------
California True
Ohio False
Oregon False
Texas False
dtype: bool
Series对象自身和其索引都有name属性,这个特性与pandas其他重要功能集成在一起:
obj.name = 'population'
obj.index.name = 'state'
print(obj)
--------------------------------
state
California NaN
Ohio 35000.0
Oregon 16000.0
Texas 71000.0
Name: population, dtype: float64
Series的索引可以通过按位置赋值的方式进行改变:
obj.index = [0,1,2,3]
print(obj)
--------------------------------
0 NaN
1 35000.0
2 16000.0
3 71000.0
Name: population, dtype: float64
1.2DataFrame
DataFrame表示的是矩阵的数据表,它包含已排序的列集合,每一列可以是不同的值类型(数值、字符串、布尔值等)。DataFrame既有行索引也有列索引,它可以被视为一个共享相同索引的Series的字典。在DataFrame中,数据被存储为一个以上的二维块,而不是列表、字典或其他一维数组的组合。尽管DataFrame是二维的,但是我们可以利用分层索引在DataFrame中展现更高维度的数据。
有多种方式可以构建DataFrame,其中最常用的方式是利用包含等长度列表或NumPy数组的字典来形成DataFrame:
data = {'state':['Ohio','Ohio','Ohio','Nevada','Nevada','Nevada'],
'year':[2000,2001,2002,2001,2002,2003],
'pop':[1.5,1.7,3.6,2.4,2.9,3.2]}
frame = pd.DataFrame(data)
print(frame)
--------------------------
state year pop
0 Ohio 2000 1.5
1 Ohio 2001 1.7
2 Ohio 2002 3.6
3 Nevada 2001 2.4
4 Nevada 2002 2.9
5 Nevada 2003 3.2
对于大型的DataFrame,head方法将会只选出头部的五行:
print(frame.head())
--------------------
state year pop
0 Ohio 2000 1.5
1 Ohio 2001 1.7
2 Ohio 2002 3.6
3 Nevada 2001 2.4
4 Nevada 2002 2.9
如果指定了列的顺序,DataFrame的列将会按照指定顺序排列:
print(pd.DataFrame(data,columns=['year','state','pop']))
--------------------
year state pop
0 2000 Ohio 1.5
1 2001 Ohio 1.7
2 2002 Ohio 3.6
3 2001 Nevada 2.4
4 2002 Nevada 2.9
5 2003 Nevada 3.2
如果传的列不包含在字典中,将会在结果中出现缺失值:
frame2 = pd.DataFrame(data,columns=['year','state','pop','debt'],
index = ['one','two','three','four','five','six'])
print(frame2)
-----------------------------
year state pop debt
one 2000 Ohio 1.5 NaN
two 2001 Ohio 1.7 NaN
three 2002 Ohio 3.6 NaN
four 2001 Nevada 2.4 NaN
five 2002 Nevada 2.9 NaN
six 2003 Nevada 3.2 NaN
DataFrame中的一列,可以按字典型标记或属性那样检索为Series:
print(frame2['state'])
--------------------------
one Ohio
two Ohio
three Ohio
four Nevada
five Nevada
six Nevada
Name: state, dtype: object
print(frame2.year)
--------------------------
one 2000
two 2001
three 2002
four 2001
five 2002
six 2003
Name: year, dtype: int64
frame2[column]对任意列名均有效,但是frame2.column只在列名是有效的python变量名有效。
这里要注意的是,返回的Series与原DataFrame有相同的索引,且Series的name属性也会被合理地设置。
行也可以通过位置或特殊属性loc进行选取:
print(frame2.loc['three'])
--------------------------
year 2002
state Ohio
pop 3.6
debt NaN
Name: three, dtype: object
列的索引是可以修改的,例如,空的‘debt’列可以赋值为标量值或值数组:
frame2['debt'] = 16.5
print(frame2)
------------------------------
year state pop debt
one 2000 Ohio 1.5 16.5
two 2001 Ohio 1.7 16.5
three 2002 Ohio 3.6 16.5
four 2001 Nevada 2.4 16.5
five 2002 Nevada 2.9 16.5
six 2003 Nevada 3.2 16.5
frame2['debt'] = np.arange(6)
print(frame2)
------------------------------
year state pop debt
one 2000 Ohio 1.5 0
two 2001 Ohio 1.7 1
three 2002 Ohio 3.6 2
four 2001 Nevada 2.4 3
five 2002 Nevada 2.9 4
six 2003 Nevada 3.2 5
将列表或数组赋值给一个列时,值的长度必须和DataFrame的长度相匹配。如果将Series赋值给一列时,Series的索引将会按照DataFrame的索引重新排列,并在空缺的地方填充缺失值:
val = pd.Series([-1.2,-1.5,-1.7],index = ['two','four','five'])
frame2['debt'] = val
print(frame2)
------------------------------
year state pop debt
one 2000 Ohio 1.5 NaN
two 2001 Ohio 1.7 -1.2
three 2002 Ohio 3.6 NaN
four 2001 Nevada 2.4 -1.5
five 2002 Nevada 2.9 -1.7
six 2003 Nevada 3.2 NaN
如果被赋值的列并不存在,则会生成一个新的列。del关键字可以像在字典中那样对DataFrame删除列。
在del的例子中,我们首先增加一列,这一列是布尔值,判断条件是state列是否为’Ohio’:
frame2['eastern'] = frame2.state == 'Ohio'
print(frame2)
--------------------------------------
year state pop debt eastern
one 2000 Ohio 1.5 NaN True
two 2001 Ohio 1.7 NaN True
three 2002 Ohio 3.6 NaN True
four 2001 Nevada 2.4 NaN False
five 2002 Nevada 2.9 NaN False
six 2003 Nevada 3.2 NaN False
这里要注意的是frame2.eastern的语法无法创建新的列。
del方法可以用于移除之前新建的列:
del frame2['eastern']
print(frame2.columns)
------------------------------------------------------
Index(['year', 'state', 'pop', 'debt'], dtype='object')
从DataFrame中选取的列是数据的视图,而不是拷贝。因此,对Series的修改会映射到DataFrame中。如果需要复制,则应当显式地使用Series的copy方法。
另一种常用的数据形式是包含字典的嵌套字典,如果嵌套字典被赋值给DataFrame,pandas会将字典的键作为列,将内部字典的键作为行索引:
pop = {'Nevada':{2001:2.4,2002:2.9},
'Ohio':{2000:1.5,2001:1.7,2002:3.6}}
frame3 = pd.DataFrame(pop)
print(frame3)
------------------
Nevada Ohio
2000 NaN 1.5
2001 2.4 1.7
2002 2.9 3.6
也可以使用类似NumPy的语法对DataFrame进行转置操作:
print(frame3.T)
------------------------
2000 2001 2002
Nevada NaN 2.4 2.9
Ohio 1.5 1.7 3.6
包含Series的字典也可以用于构造DataFrame:
pdata = {'Ohio':frame3['Ohio'][:-1],
'Nevada':frame3['Nevada'][:2]}
print(pd.DataFrame(pdata))
------------------
Ohio Nevada
2000 1.5 NaN
2001 1.7 2.4
如果DataFrame的索引和列拥有name属性,则这些name属性也会被显示:
frame3.index.name = 'year'
frame3.column.name = 'state'
print(frame3)
-------------------
state Nevada Ohio
year
2000 NaN 1.5
2001 2.4 1.7
2002 2.9 3.6
和Series类似,DataFrame的values属性会将包含在DataFrame中的数据以二维ndarray的形式返回:
print(frame3.values)
---------
[[nan 1.5]
[2.4 1.7]
[2.9 3.6]]
如果DataFrame的列是不同的dtypes,则values的dtype会自动选择适合所有列的类型:
print(frame2.values)
-------------------------
[[2000 'Ohio' 1.5 nan]
[2001 'Ohio' 1.7 -1.2]
[2002 'Ohio' 3.6 nan]
[2001 'Nevada' 2.4 -1.5]
[2002 'Nevada' 2.9 -1.7]
[2003 'Nevada' 3.2 nan]]
1.3索引对象
pandas中的索引对象是用于存储轴标签和其他元数据的(例如轴名称或标签)。在构造Series或DataFrame时,我们所使用的任意数组或标签序列都可以在内部转换为索引对象:
obj = pd.Series(range(3),index = ['a','b','c'])
index = obj.index
print(index)
--------------------------------------
Index(['a', 'b', 'c'], dtype='object')
print(index[1:])
---------------------------------
Index(['b', 'c'], dtype='object')
索引对象是不可变的,因此用户是无法修改索引对象的。
不变性使得在多种数据结构中分享索引对象更为安全:
labels = pd.Index(np.arange(3))
print(labels)
------------------------------------
Int64Index([0, 1, 2], dtype='int64')
obj2 = pd.Series([1.5,-2.5,0],index = labels)
print(obj2)
--------------
0 1.5
1 -2.5
2 0.0
dtype: float64
print(obj2.index is labels)
----
True
除了类似数组,索引对象也像一个固定大小的集合:
print(frame3.columns)
-----------------------------------------
Index(['Nevada', 'Ohio'], dtype='object')
print('Ohio' in frame3.columns)
----
True
print(2003 in frame3.index)
-----
False
与python集合不同,pandas索引对象可以包含重复标签:
dup_labels = pd.Index(['foo','foo','bar','bar'])
print(dup_labels)
---------------------------------------------------
Index(['foo', 'foo', 'bar', 'bar'], dtype='object')
表1-1:一些索引对象的方法和属性
| 方法 | 描述 |
|---|---|
| append | 将额外的索引对象粘贴到原索引后,产生一个新的索引 |
| difference | 计算两个索引的差集 |
| intersection | 计算两个索引的交集 |
| union | 计算两个索引的并集 |
| isin | 计算表示每一个值是否在传值容器中的布尔数组 |
| delete | 将位置i的元素删除,并产生新的索引 |
| drop | 根据传参删除指定索引值,并产生新的索引 |
| insert | 在位置i插入元素,并产生新的索引 |
| is_monotonic | 如果索引序列递增则返回True |
| is_unique | 如果索引序列唯一则返回True |
| unique | 计算索引的唯一值序列 |
来源:CSDN
作者:圆碌碌肥嘟嘟
链接:https://blog.csdn.net/weixin_43303087/article/details/84385951