pandas含有使数据清洗和分析工作变得更快更简单的数据结构和操作工具。
pandas数据类型结构
Series和DataFrame是pandas两个主要的数据结构。
Series
Series是一种类似于一维数组的对象,它由一组数据(各种NumPy数据类型)以及一组与之相关的数据标签(即索引)组成。
仅由一组数据即可产生最简单的Series:
import pandas as pd
from pandas import Series,DataFrame
obj = Series([4,7,-5,3])
ob
0 4
1 7
2 -5
3 3
dtype: int64
Series的字符串表现形式为:索引在左边,值在右边。上例没有为数据指定索引,于是会自动创建一个0到N-1(N为数据的长度)的整数型索引。
可以通过Series 的values和index属性获取其数组表示形式和索引对象:
>>> obj.values
array([ 4, 7, -5, 3], dtype=int64)
>>> obj.index
RangeIndex(start=0, stop=4, step=1)
创建带索引的Series:
>>> obj2 = pd.Series([4,7,-5,3],index=['d','b','a','c'])
>>> obj2
d 4
b 7
a -5
c 3
dtype: int64
选取Seriesde中的单个或一组值:
>>> obj2['a']
-5
>>> obj2[['c','a','d']]
c 3
a -5
d 4
dtype: int64
Numpy数组运算(根据布尔型书进行过滤、标量乘法、应用数学函数等)都会保留索引和值之间的链接:
>>> obj2
d 4
b 7
a -5
c 3
dtype: int64
>>> obj2[obj2 > 0]
d 4
b 7
c 3
dtype: int64
可以将Series看成是一个定长的有序字典,因为他是索引值到数据值的一个映射 。可以用字典函数:
>>> 'b' in obj2
True
通过字典创建Series:
sdata = {'Ohio':35000,'Texas':71000,'Oregon':16000,'Utah':5000}
obj3 = pd.Series(sdata)
obj3
Ohio 35000
Texas 71000
Oregon 16000
Utah 5000
dtype: int64
传入排好序的字典的键改变顺序
states = ['California','Ohio','Oregon','Texas']
obj4 = pd.Series(sdata,index=states)
obj4
California NaN
Ohio 35000.0
Oregon 16000.0
Texas 71000.0
dtype: float64
上例中,sdata中跟states索引匹配的那3个值会被找出来并放到相应的位置上
“Clifornia”对应的值到不到,结果就是NaN(非数字 not a number)pandas中,NaN表示缺失值或NA值。
pandas的isnull和notnull函数用于检测缺失数据:
pd.isnull(obj4)
California True
Ohio False
Oregon False
Texas False
dtype: bool
Series类似的实例方法:
>>> obj4.isnull()
California True
Ohio False
Oregon False
Texas False
dtype: bool
Series最重要的一个功能是会根据运算的索引标签自动对齐数据:可以认为是类似Join的操作
>>> obj3
Ohio 35000
Texas 71000
Oregon 16000
Utah 5000
dtype: int64
>>> obj4
California NaN
Ohio 35000.0
Oregon 16000.0
Texas 71000.0
dtype: float64
>>> obj3 + obj4
California NaN
Ohio 70000.0
Oregon 32000.0
Texas 142000.0
Utah NaN
dtype: float64
Series对象本身以及其索引都有一个name属性,该属性跟pandas其他关键功能关系非常密切:
obj4.name = 'population'
obj4.index.name = 'state'
obj4
state
California NaN
Ohio 35000.0
Oregon 16000.0
Texas 71000.0
Name: population, dtype: float64
Series索引可以通过赋值的方式就地修改:
>>> obj
0 4
1 7
2 -5
3 3
dtype: int64
obj.index = ['Bob','Steve','Jeff','Ryan']
obj
Bob 4
Steve 7
Jeff -5
Ryan 3
dtype: int64
DataFrame
DataFrame是一个表格型的数据结构,它含有一组有序的序列,每列可以是不同的值类型(数值、字符串、布尔值)
DateFame 既有行索引也有列索引。
DataFrame中的数据是通过一个或多个二维块存放的(而不是列表、字典或别的一维数组结构)
注:虽然DataFrame是以二维结构保存数据的,但仍然可以轻松的将其表示为更高纬度的数据(层次化索引的表格型结构,这是pandas中许多高级处理功能的关键要素)
创建DataFrame
最常用的一种是直接传入一个由等长列表或NumPy数组组成的字典:
data = {'state':['Ohio','Ohio','Ohio','Nevada','Nevada'],
'year':[2000,2001,2002,2001,2002],
'pop':[1.5,1.7,3.6,2.4,2.9]}
frame = DataFrame(data)
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
按照制定的序列排序
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
跟Series一样,如果传入的列在数据中找不到,就会产生NA值:
frame2 = DataFrame(data,columns=['year','state','pop','debt'],
index = ['one','two','three','four','five'])
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
>>> frame2.columns
Index(['year', 'state', 'pop', 'debt'], dtype='object')
获取DataFrame列为一个Series:
>>> frame2['state']
one Ohio
two Ohio
three Ohio
four Nevada
five Nevada
Name: state, dtype: object
>>> frame2.year
two 2001
three 2002
four 2001
five 2002
Name: year, dtype: int64
注意到返回的Series拥有原DataFrame相同的索引,但其name 属性也被相应的设置好了。
获取一行
frame2.loc['three']
year 2002
state Ohio
pop 3.6
debt NaN
Name: three, dtype: object
通过赋值的方式修改列值,可以赋值一个标量或一组值
frame2['debt']=16.5
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
frame2['debt'] = np.arange(5.)
frame2
year state pop debt
one 2000 Ohio 1.5 0.0
two 2001 Ohio 1.7 1.0
three 2002 Ohio 3.6 2.0
four 2001 Nevada 2.4 3.0
five 2002 Nevada 2.9 4.0
将列表或数组赋值给某个列时,其长度必须跟DateFrame的长度匹配。
如果赋值的是一个Series,就会精确匹配到DataFrame的索引,所有的空位都将被填上缺失值
val = pd.Series([-1.2,-1.5,-1.7],index=['two','four','five'])
frame2['debt'] = val
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
创造新列
frame2['eastern'] = frame2.state == 'Ohio'
frame2
year state pop debt eastern
one 2000 Ohio 1.5 0.0 True
two 2001 Ohio 1.7 1.0 True
three 2002 Ohio 3.6 2.0 True
four 2001 Nevada 2.4 3.0 False
five 2002 Nevada 2.9 4.0 False
删除列
del frame2['eastern']
frame2.columns
Index(['year', 'state', 'pop', 'debt'], dtype='object')
警告:通过索引方式返回的列值只是相应数据的视图,并不是副本。因此对返回的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 = DataFrame(pop)
frame3
Nevada Ohio
2000 NaN 1.5
2001 2.4 1.7
2002 2.9 3.6
使用Numpy数组方法,对DataFrame进行转置(交换行列):
frame3.T
2000 2001 2002
Nevada NaN 2.4 2.9
Ohio 1.5 1.7 3.6
内层字段的键会被合并、排序以形成最终的索引。如果显示指定,则按照指定顺序排序:
DataFrame(pop,index=[2001,2002,2003])
Nevada Ohio
2001 2.4 1.7
2002 2.9 3.6
2003 NaN NaN
由Series组成的字典差不多也是一样的用法:
pdata = {'Ohio':frame3['Ohio'][:-1],
'Nevada':frame3['Nevada'][:2]}
DataFrame(pdata)
Ohio Nevada
2000 1.5 NaN
2001 1.7 2.4

如果设置了DataFrame的index和columns的name属性,则这些信息也会被显示出来:

跟Series一样,values属性也会以二维ndarry的形式返回
frame3.values
array([[nan, 1.5],
[2.4, 1.7],
[2.9, 3.6]])
如果DataFrame各类的数据类型不同,则数据组的数据类型就会选用能兼容所有列的数据类型:
frame2.values
array([[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]], dtype=object)
索引对象
pandas的索引对象负责管理轴标签和其他元数据(比如轴名称)。构建Series或DataFrame时,所用到的任何数组或其他序列的标签都会被转换成一个Index.

Index对象是不可修改的(immutable),因此用户不能对其修改:
index[1] = 'd'
Exception:<class 'pandas.core.index.Index'>onject is immutable
不可修改性非常重要,因为这样才能使Index对象在多个数据结构之间安全共享:

注:虽然用户不经常使用Index的功能,但是因为一些操作会生成包含被索引化的数据,理解它们的工作原理是很重要的。
除了长的像数组,Index的功能也类似一个固定大小的集合:

每个索引都有一些方法和属性,它们可用于设置逻辑并回答有关该索引包含的数据的常见问题。

2、基本功能
重新索引
pandas对象的一个重要方法是reindex,其作用是创建一个适应新索引的新对象。
调用Series的reindex将会根据索引进行重排,如果某个索引值当前不存在,就引入缺失值:
obj = pd.Series([4.5,7.2,-5.3,3.6],index=['d','b','a','c'])
obj
d 4.5
b 7.2
a -5.3
c 3.6
dtype: float64
obj2 = obj.reindex(['a','b','c','d','e'])
obj2
a -5.3
b 7.2
c 3.6
d 4.5
e NaN
dtype: float64
对于时间序列这样的有序数据,重新索引时可能需要做一些插值处理。method选项即可达到此目的
下表列出了method选项。其实我们有时需要比向前和向后填充更为精准的插值方式。
下表列出了method选项。其实我们有时需要比向前和向后填充更为精准的插值方式。
| 参数 |
说明 |
| ffill或pad | 向前填充(或搬运)值 |
| bfill或backfill | 向后填充(或搬运)值 |
对于DataFrame,reindex可以修改索引(行)和列,或两个都修改。如果仅传入一个序列,则会重新索引行:

使用columns关键字即可重新索引列:

也可以同时对行和列进行索引,而插值只能按行应用:
frame = pd.DataFrame(np.arange(9).reshape(3,3),
index=['a','c','d'],
columns=['Onio','Texas','California'])
states = ['Texas','Utah','California']
frame.reindex(index=['a','b','c','d'],columns=states).ffill()
Texas Utah California
a 1.0 NaN 2.0
b 1.0 NaN 2.0
c 4.0 NaN 5.0
d 7.0 NaN 8.0
删除指定轴上的项
丢弃一条轴或某条轴上的项跟简单,只要有一个索引数组或列表即可。
由于需要执行一些数据整合和集合逻辑,所以drop方法返回的是一个在指定轴上删除了指定值的新对象(原对象不变)
obj = Series(np.arange(5.),index=['a','b','c','d','e'])
new_obj = obj.drop('c')
new_obj
a 0.0
b 1.0
d 3.0
e 4.0
dtype: float64
obj
a 0.0
b 1.0
c 2.0
d 3.0
e 4.0
dtype: float64
obj.drop(['d','c'])
a 0.0
b 1.0
e 4.0
dtype: float64
obj
a 0.0
b 1.0
c 2.0
d 3.0
e 4.0
dtype: float64
对于DataFrame ,可以删除任意轴上的索引值

索引、选取和过滤
Series索引(obj[...])的工作方式类似于Numpy数组的索引,只不过Series的索引值不只是整数。

注意:因为pandas对象的index不限于整数,所以当使用非整数(标签切片)作为切片索引时,它是末端包含的。

DataFrame选取行
pandas以类似字典的方式来获取某一列的值,比如df['A'],这会得到df的A列,返回的也是一个Series对象。如果想要获取部分行的话就得用到切片
例如:df'[:3],获取前三行;df[3:4],获取第四行。但是如果想要获取部分行部分列的上述两种方法就无能为力了。这时就得用到 ix, loc, iloc方法(ix已弃用)loc是指location的意思,iloc中的i是指integer。iloc和loc方式索引也更为精细。这两者的区别如下:
loc works on labels in the index.(说白了就是标签索引)
iloc works on the positions in the index (so it only takes integers). (位置索引,和列表索引类似,里面只能是数字)
直接进行切片的情况就特殊了:
-
索引时,选取的是列
-
切片时,选取的是行


使用布尔型数组的情况,注意行和列的不同切法

算数运算和数据对其
pandas最重要的一个功能是,它可以对不同索引的对象进行算数运算。
在将对象相加时,结果的索引取索引对的并集。

自动的数据对齐操作在不重叠的索引处引入了空值,默认为NaN.
DataFrame的对齐操作会同时发生在列和行上
df1 = DataFrame(np.arange(9.).reshape(3,3),columns=list('bcd'),
index=['Ohio','Texas','Colorado'])
df2 = DataFrame(np.arange(12.).reshape(4,3),columns=list('bde'),
index=['Utah','Ohio','Texas','Oregon'])
df1
b c d
Ohio 0.0 1.0 2.0
Texas 3.0 4.0 5.0
Colorado6.0 7.0 8.0
df2
b d e
Utah 0.0 1.0 2.0
Ohio 3.0 4.0 5.0
Texas 6.0 7.0 8.0
Oregon 9.0 10.0 11.0
df1+df2 #相加后会产生一个新的DataFrame,其索引和列为原来那两个DataFrame的并集:
b c d e
ColoradoNaN NaN NaN NaN
Ohio 3.0 NaN 6.0 NaN
Oregon NaN NaN NaN NaN
Texas 9.0 NaN 12.0 NaN
Utah NaN NaN NaN NaN
当不希望在结果中出现NA值时,使用df1的add方法,传入df2以及一个fill_value参数:
df1.add(df2,fill_value=0)
b c d e
Colorado6.0 7.0 8.0 NaN
Ohio 3.0 1.0 6.0 5.0
Oregon 9.0 NaN 10.0 11.0
Texas 9.0 4.0 12.0 8.0
Utah 0.0 NaN 1.0 2.0
其他算数方法
| 方法 | 说明 |
| add | 用于加法 |
| sub | 减法 |
| div | 除法 |
| mul | 乘法 |
DataFrame和Series之间的运算
默认情况下,DataFrame和Series之间的算术运算会将Series的索引匹配到DataFrame的列,然后沿着行一直向下广播:


如果某个索引值在DataFrame的列或Series的索引中找不到,则参与运算的两个对象就会被重新索引以形成并集
series2 = pd.Series(range(3),index=['b','e','f'])
series2
b 0
e 1
f 2
dtype: int64
frame
b d e
Utah 0.0 1.0 2.0
Ohio 3.0 4.0 5.0
Texas 6.0 7.0 8.0
Oregon 9.0 10.0 11.0
frame + series
b d e f
Utah 0.0 NaN 3.0 NaN
Ohio 3.0 NaN 6.0 NaN
Texas 6.0 NaN 9.0 NaN
Oregon 9.0 NaN 12.0 NaN
如果需要匹配行且在列上广播,则必须使用算术运算方法。例如:

axis=0:纵向 axis=1横向

函数应用和映射
Numpu的unfuncs(元素级数组方法)也可用于操作pandas对象:

apply方法:
另一个常见的的操作:将函数应用到由各列或行所形成的一维数组上。使用DataFrame的apply方法:

上面函数f,计算了每列Series的最大值和最小值,在frame的每列都执行了一次。
结果是一个Series,使用frame的列名作为索引。
在每行执行函数需要传递axis='columns'或axis=1到apply

注:许多常见的数组统计功能都被实现成DataFrame的方法,如sum和mean.因此无需使用apply方法。
传到apply的函数不是必须是一个标量,还可以返回由多个值组成的Series:

元素级的Python函数也是可以使用的。假如想得到frame中的各个浮点值的格式化字符串,使用applymap即可:
之所以叫applymap,是因为Series有一个应用于元素级函数的map方法:

排序和排名
排序:
根据条件对数据排序是一种很重要的内置运算。
对行或列的索引排序:sort_index方法,返会一个已经排好序的新对象:

对于DateFrame,则可以根据任意一个轴上的索引进行排序:

数据默认是按升序排序的,但也可以降序排序:

按值排序 使用sort_values方法:

在排序时,任何缺失值都会被放到Series的末尾

当排序一个DataFrame时,可能会根据一个或多个列中的值进行排序。
将一个或多个列的名字传递给sort_values的by选项即可。

根据多个列进行排序,传入名称的列表即可:

排名:
排名(Series.rank(method='average',ascending=True))的作用与排序的不同之处在于,他会把对象的values替换成名次(从1到n).这是唯一的问题在于如何处理平级项。方法里的method参数就是起这个作用的,他有四个值可选:average,min,max,first。
默认是average(为各组分配一个平均排名).

DataFrame的.rank(axis=0,method='average',ascending=True)方法多个了axis参数,可选择按行或列分别进行排名。

带有重复值的轴索引
目前为止的所有范例都有着唯一的轴标签(索引值)。虽然许多pandas函数(如reindex)都要求标签唯一,但这并不是强制性的。
下面是个简单的带有重复索引值的Series:

索引的.is_unique属性可以告诉你它的值是否是唯一的:

对于带有重复值的索引,数据选取的行为将会有些不同。
如果索引对应多个值,则返回一个 Series;而对应单个值的,则返回一个标量值:

对DateFrme的行索引时也是如此:

汇总和计算描述统计
pandas对象有一些统计方法。它们大部分都属于约简和汇总统计,用于从Series中提取单个值,或从Dataframe行或列中提取一个Series。
比如DataFrame.sum(axis=0,shipna=True)方法,当数据集中存在NA值时,这些值会被简单跳过,除非整个切片(行或列)全是NA,如果不想这样, 则可以通过skip=False来禁用此功能:


其他常用的统计方法有:

其中有些方法(如idxmin和idxmax)返回的是间接统计(比如达到最小值和最大值的索引):

另一些方法则是累积型的:

还有一种方法,它既不是约简型也不是累计型.describe就是一个例子,它用于一次性产生多个汇总统计:

对于非数值型数据,describe会产生另外一种汇总统计:

相关系数与协方差
Series的corr方法用于计算两个Series中重叠的、非NA的、按索引对齐的值的相关系数。与此类似,cov用于计算协方差:


另一方面,DataFrame的corr和cov方法将以DataFrame的形式分别返回完整的相关系数或协方差矩阵:
利用DataFrame的corrwith方法,你可以计算其列或行跟另一个Series或DataFrame之间的相关系数。传入一个Series将会返回一个相关系数值Series(针对各列进行计算):

无论如何,在计算相关系数之前,所有的数据项都会按标签对齐。
唯一值、值计数以及成员资格
函数unique可以得到Series中的唯一值数组:series.unique(),可用uniques.sort()排序
series.value_counts() 得到各值出现的频数,默认按照值频率降序排序。
pd.value_counts(series.values, sort=False) 用于任何数组或序列,sort参数表示不按频数大小排序
isin用于判断矢量化集合的成员资格,可用于过滤Series中或DataFrame列中数据的子集:series.isin(['b', 'c'])
与isint 类似的是Index.get_indexer方法。它返回一个索引数组,是一个数组元素在另一个没有重复元素的数组中的位置

有时,可能希望得到DataFrame中多个相关列的一张柱状图,例如

将pandas.value_counts传给DataFrame的apply函数,就会变成元素次数统计

这里,结果中的行标签是所有行的唯一值,后面的频率是每个列中这些值的相应计数。
处理缺失值
处理数据在大部分应用中都很常见,pandas中NA的表现为np.nan,另外pytho的内建的None也会被当做NA处理。
处理NA的方法有四种:dropna,fillna,isnull,notnull.
is(not) null:
这一方法对对象做元素级应用,然后返回一个布尔型数组,一般可用于布尔型索引。
dropna
对于一个Series,dropna返回一个仅含非空数据和索引值的Series.
from numpy import nan as NA
data = Series([1,NA,3.5,NA,7])
data.dropna()
0 1.0
2 3.5
4 7.0
dtype: float64
问题在于DataFrame的处理方式,因为一旦drop的话至少丢掉一行(一列)
from pandas import DataFrame
data = DataFrame([[1.,6.5,3.],[1,NA,NA],[NA,NA,NA],[NA,6.5,3.]])
data
0 1 2
0 1.0 6.5 3.0
1 1.0 NaN NaN
2 NaN NaN NaN
3 NaN 6.5 3.0
data.dropna()
0 1 2
0 1.0 6.5 3.0
这里的解决方式与前面类似。还是通过一个额外的参数:
dropna(axis=0,how='any',thresh=None)
how ='all'时将只丢弃全为NA的那些行:
data.dropna(how='all')
0 1 2
0 1.0 6.5 3.0
1 1.0 NaN NaN
3 NaN 6.5 3.0
data[4]=NA
data
0 1 2 4
0 1.0 6.5 3.0 NaN
1 1.0 NaN NaN NaN
3 NaN 6.5 3.0 NaN
data.dropna(axis=1,how='all') #df.drop(name, axis=1) 代表将name对应的列标签(们)沿着水平的方向依次删掉。
0 1 2
0 1.0 6.5 3.0
1 1.0 NaN NaN
2 NaN NaN NaN
3 NaN 6.5 3.0
另一个参数是thresh,该参数的类型为整数,它的作用是,比如thresh=3,会在一行中至少有3个非NA值时将其保留。
fillna:
将缺失值替换为指定值
fillna(value=None,method=None,axis=0)//value除了基本类型外还可以使用字典,这样可以实现对不同列填充不同的值。
data
0 1 2 4
0 1.0 6.5 3.0 NaN
1 1.0 NaN NaN NaN
2 NaN NaN NaN NaN
3 NaN 6.5 3.0 NaN
data.fillna(0)
0 1 2 4
0 1.0 6.5 3.0 0.0
1 1.0 0.0 0.0 0.0
2 0.0 0.0 0.0 0.0
3 0.0 6.5 3.0 0.0
data.fillna({1:0.5,2:-1})
0 1 2 4
0 1.0 6.5 3.0 NaN
1 1.0 0.5 -1.0 NaN
2 NaN 0.5 -1.0 NaN
3 NaN 6.5 3.0 NaN
fillna默认会返回新对象,但是也可以实现对现有对象进行就地修改:
df.fillna(0,inplace=True)
对reindex有效的那些插值方法也可用于fillna:
df = DataFrame(np.random.randn(6,3))
df.iloc[2:,1] = NA
df.iloc[4:,2] = NA
df
0 1 2
0 1.131594 -0.021476 1.249211
1 0.172879 -0.699232 0.069015
2 -0.315513 -0.699232 -0.776022
3 0.143327 -0.699232 -0.954425
4 0.382919 -0.699232 -0.954425
5 0.052213 -0.699232 -0.954425
df.fillna(method='ffill')
0 1 2
0 1.131594 -0.021476 1.249211
1 0.172879 -0.699232 0.069015
2 -0.315513 -0.699232 -0.776022
3 0.143327 -0.699232 -0.954425
4 0.382919 -0.699232 -0.954425
5 0.052213 -0.699232 -0.954425
df.fillna(method='ffill',limit=2)
0 1 2
0 1.131594 -0.021476 1.249211
1 0.172879 -0.699232 0.069015
2 -0.315513 -0.699232 -0.776022
3 0.143327 -0.699232 -0.954425
4 0.382919 NaN -0.954425
5 0.052213 NaN -0.954425
可以利用fillna实现许多别的功能。比如说,可以传入Series的平均值或中位数:
data = Series([1.,NA,3.5,NA,7])
data.fillna(data.mean())
0 1.000000
1 3.833333
2 3.500000
3 3.833333
4 7.000000
dtype: float64

层次化索引
层次化索引是pandas的一项重要功能,它能使你在一个轴上拥有多个(两个以上)索引级别。

stack函数会将数据从"表格结构"变成"花括号结构"
unstack 函数将数据从"花括号结构"变成“表格结构”
例子:
data = Series(np.random.randn(10),
index=[['a','a','a','b','b','b','c','c','d','d'],
[1,2,3,1,2,3,1,2,2,3]])
data
a 1 1.600137
2 0.301853
3 0.041740
b 1 -0.098636
2 -1.656555
3 -0.768834
c 1 0.299663
2 0.626259
d 2 0.607036
3 1.764293
dtype: float64
#选取子集
data['b']
1 -0.098636
2 -1.656555
3 -0.768834
dtype: float64
#内层选取
data[:,2]
a 0.301853
b -1.656555
c 0.626259
d 0.607036
dtype: float64
stack和unstack:
data.unstack()
1 2 3
a 1.600137 0.301853 0.041740
b -0.098636 -1.656555 -0.768834
c 0.299663 0.626259 NaN
d NaN 0.607036 1.764293
#unstack的逆运算是stack:
data.unstack().stack()
a 1 1.600137
2 0.301853
3 0.041740
b 1 -0.098636
2 -1.656555
3 -0.768834
c 1 0.299663
2 0.626259
d 2 0.607036
3 1.764293
dtype: float64
DataFrame每条轴都可以有分层索引:



可以单独创建MultiIndex,然后复用

重排分级顺序
有时需要重新调整某条轴上的顺序,或根据指定级别上的值对数据进行排序。
swaplevel接受两个级别编号或名称,并返回一个互换了级别的新对象(但数据不会发生变化):

根据级别汇总统计
许多Dataframe和Series的描述和汇总统计都有一个level选项,它用于指定在某条轴上求和的级别。

这其实是利用了pandas的groupby功能。
DataFrame的行列转化
要将DataFrame 的一个或多个列当做行索引来用,或者望将行索引变成DataFrame的列。
frame = DataFrame({'a':range(7),'b':range(7,0,-1),
'c':['one','one','one','two','two','two','two'],
'd':[0,1,2,0,1,2,3]})
frame
a b c d
0 0 7 one 0
1 1 6 one 1
2 2 5 one 2
3 3 4 two 0
4 4 3 two 1
5 5 2 two 2
6 6 1 two 3
DataFrame的set_indes函数会将其一个或多个列转化为行索引,并创建一个 新的DataFrame:
这其实使用3,4列做了一次分组汇总
默认情况下,那些列会从DataFrame中移除,但是也可以将其保留下来:

reset_index的功能跟set_index刚好相反,层次化索引的级别会被转移到列里面:

其他有关pandas 的话题:整数索引
有整数索引的pandas对象,跟内置的Python数据结构(如列表或元组)在索引予以上有些不同。
ser = Series(np.arange(3.))
ser[-1] #报错,因为整数索引的歧义性
这里有一个含有0、1、2的索引,很难推断出用户想要什么(基于标签或位置的索引)
相反对于一个非整数索引,就没有这样的歧义
ser2 = Series(np.arange(3.),index=['a','b','c'])
ser2[-1]
2.0
本文详细介绍了pandas的数据结构,包括Series和DataFrame,重点讲解了它们的创建、索引、选取、过滤、算数运算以及缺失值处理等核心功能。此外,还涉及了层次化索引和数据重塑等高级操作。
1211

被折叠的 条评论
为什么被折叠?



