pandas 入门
pandas 的数据结构介绍
pandas 有两个重要的数据结构:Series和DataFrame。
Series
Series是一个一维的类似的数组对象,包含一个数组的数据(任何NumPy的数据类型)和一个与数组关联的数据标签,被叫做 索引 。
obj = Series([4, 7, -5, 3])
obj
Ou:
0 4
1 7
2 -5
3 3
# 如果没有给数据指定索引,一个包含整数0到 N-1 (这里N是数据的长度)的默认索引被创建。
obj.values
Out: array([ 4, 7, -5, 3])
obj.index
Out: Int64Index([0, 1, 2, 3])
obj2 = Series([4, 7, -5, 3], index=['d', 'b', 'a', 'c'])
obj2
Out:
d 4
b 7
a -5
c 3
Series是一个定长的有序的字典,因为它把索引和值映射起来了。
'b' in obj2
Out: True
'e' in obj2
Out: False
可以通过传递一个 Python 字典来创建一个 Series:
sdata = {'Ohio': 35000, 'Texas': 71000, 'Oregon': 16000, 'Utah': 5000}
obj3 = Series(sdata)
obj3
Out: # 结果是按照索引排序后的顺序
Ohio 35000
Oregon 16000
Texas 71000
Utah 5000113
states = [‘California’, ‘Ohio’, ‘Oregon’, ‘Texas’]
obj4 = Series(sdata, index=states)
obj4
Out:
California NaN
Ohio 35000
Oregon 16000
Texas 71000
在这种情况下, sdata 中的3个值被放在了合适的位置,但因为没有发现对应于 ‘California’ 的值,就出现了 NaN (不是一个数),这在pandas中被用来标记数据缺失或 NA 值。我使用“missing”或“NA”来表示数度丢失。在pandas中用函数 isnull 和 notnull 来检测数据丢失:
pd.isnull(obj4) # 或者使用实例方法obj4.isnull()
Out[26]:
California True
Ohio False
Oregon False
Texas False
Series的一个重要的功能是:它在运算中会自动对齐不同索引的数据。
obj3 + obj4
Out:
California NaN
Ohio 70000
Oregon 32000
Texas 142000
Utah NaN
Series对象本身和它的索引都有一个 name 属性,它和pandas的其它一些关键功能整合在一起:
obj4.name = 'population'
obj4.index.name = 'state'
obj4
Out:
state
California NaN
Ohio 35000
Oregon 16000
Texas 71000
Name: population
DataFrame
一个Datarame表示一个表格,类似电子表格的数据结构,包含一个经过排序的列表集,它们没一个都可以有不同的类型值(数字,字符串,布尔等等)。
有很多方法来构建一个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
Out:
pop state year
0 1.5 Ohio 2000
1 1.7 Ohio 2001
2 3.6 Ohio 2002
3 2.4 Nevada 2001
4 2.9 Nevada 2002
如果你设定了一个列的顺序,DataFrame的列将会精确的按照你所传递的顺序排列;和Series一样,如果你传递了一个行,但不包括在 data 中,在结果中它会表示为NA值:
frame2 = DataFrame(data, columns=['year', 'state', 'pop', 'debt'],
....: index=['one', 'two', 'three', 'four', 'five'])
frame2
Out:
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
和Series一样,在DataFrame中的一列可以通过字典记法或属性来检索:
frame2['state'] # 或是使用属性 frame2.state
Out:
one Ohio
two Ohio
three Ohio
four Nevada
five Nevada
Name: state
# 注意,返回的Series包含和DataFrame相同的索引,并它们的 name 属性也被正确的设置了。
给一个不存在的列赋值,将会创建一个新的列。 像字典一样 del 关键字将会删除列。==索引DataFrame时返回的列是底层数据的一个视窗,而不是一个拷贝。因此,任何在Series上的就地修改都会影响DataFrame。列可以使用Series的 copy 函数来显式的拷贝。==
另一种通用的数据形式是一个嵌套的字典的字典格式,如果被传递到DataFrame,它的外部键会被解释为列索引,内部键会被解释为行索引::
pop = {'Nevada': {2001: 2.4, 2002: 2.9},
....: 'Ohio': {2000: 1.5, 2001: 1.7, 2002: 3.6}}
frame3 = DataFrame(pop)
frame3
Out:
Nevada Ohio
2000 NaN 1.5
2001 2.4 1.7
2002 2.9 3.6
可以输入给 DataFrame 构造器的数据
类型 | 说明 |
---|---|
二维ndarray | 一个数据矩阵,有可选的行标和列标 |
数组,列表或元组的字典 | 每一个序列成为DataFrame中的一列。所有的序列必须有相同的长度。 |
NumPy的结构/记录数组 | 和“数组字典”一样处理 |
Series的字典 | 每一个值成为一列。如果没有明显的传递索引,将结合每一个Series的索引来形成结果的行索引。 |
字典的字典 | 每一个内部的字典成为一列。和“Series的字典”一样,结合键值来形成行索引。 |
字典或Series的列表 | 每一项成为DataFrame中的一列。结合字典键或Series索引形成DataFrame的列标。 |
列表或元组的列表 | 和“二维ndarray”一样处理 |
另一个DataFrame | DataFrame的索引将被使用,除非传递另外一个 |
NumPy伪装数组(MaskedArray) | 除了掩码值在DataFrame中成为NA/丢失数据之外,其它的和“二维ndarray”一样 |
DataFrame的 index 和 columns 有它们的 name,可以显示调用;跟 Series 一样,values 属性返回一个包含在 DataFrame 中的数据的二维 ndarray。
索引对象
pandas的索引对象用来保存坐标轴标签和其它元数据(如坐标轴名或名称)。构建一个Series或DataFrame时任何数组或其它序列标签在内部转化为索引:
obj = Series(range(3), index=['a', 'b', 'c'])
index = obj.index
index
Out: Index([a, b, c], dtype=object)
index[1:]
Out: Index([b, c], dtype=object)
索引对象是不可变的,因此不能由用户改变;索引对象的不可变性非常重要,这样它可以在数据结构中结构中安全的共享。
index[1] = 'd' # 错误
index = pd.Index(np.arange(3))
obj2 = Series([1.5, -2.5, 0], index=index)
obj2.index is index
Out: True
每个索引都有许多关于集合逻辑的方法和属性,且能够解决它所包含的数据的常见问题。
索引方法和属性
方法 | 说明 |
---|---|
append | 链接额外的索引对象,产生一个新的索引 |
diff | 计算索引的差集 |
intersection | 计算交集 |
union | 计算并集 |
isin | 计算出一个布尔数组表示每一个值是否包含在所传递的集合里 |
delete | 计算删除位置i的元素的索引 |
drop | 计算删除所传递的值后的索引 |
insert | 计算在位置i插入元素后的索引 |
is_monotonic | 返回True,如果每一个元素都比它前面的元素大或相等 |
is_unique | 返回True,如果索引没有重复的值 |
unique | 计算索引的唯一值数组 |
基本功能
主要是操作 Series 和 DataFrame 中的数据的基本手段。
重新索引
pandas对象的一个关键的方法是 reindex ,创建一个适应新索引的新对象。
obj = Series([4.5, 7.2, -5.3, 3.6], index=['d', 'b', 'a', 'c'])
obj
Out:
d 4.5
b 7.2
a -5.3
c 3.6
在Series上调用 reindex 重排数据,使得它符合新的索引,如果那个索引的值不存在就引入缺失数据值:
obj2 = obj.reindex(['a', 'b', 'c', 'd', 'e'])
obj2
Out:
a -5.3
b 7.2
c 3.6
d 4.5
e NaN
obj.reindex(['a', 'b', 'c', 'd', 'e'], fill_value=0)
Out:
a -5.3
b 7.2
c 3.6
d 4.5
e 0.0
为了对时间序列这样的数据排序,当重建索引的时候可能想要对值进行内插或填充。 method 选项可以是你做到这一点,使用一个如 ffill 的方法来向前填充值:
obj3 = Series(['blue', 'purple', 'yellow'], index=[0, 2, 4])
obj3.reindex(range(6), method='ffill')
Out:
0 blue
1 blue
2 purple
3 purple
4 yellow
5 yellow
参数 | 描述 |
---|---|
ffill或pad | 前向填充(或搬运)值 |
bfill或backfill | 后向填充(或搬运)值 |
reindex 的(插值)method 选项
参数 | 描述 |
---|---|
ffill或pad | 前向填充(或搬运)值 |
bfill或backfill | 后向填充(或搬运)值 |
对于DataFrame, reindex 可以改变(行)索引,列或两者。当只传入一个序列时,结果中的行被重新索引了:
frame = DataFrame(np.arange(9).reshape((3, 3)), index=['a', 'c', 'd'],
....: columns=['Ohio', 'Texas', 'California'])
frame
Out:
Ohio Texas California
a 0 1 2
c 3 4 5
d 6 7 8
frame2 = frame.reindex(['a', 'b', 'c', 'd'])
In [89]: frame2
Out[89]:
Ohio Texas California
a 0 1 2
b NaN NaN NaN
c 3 4 5
d 6 7 8
# 使用columns关键字指定列重新索引
states = ['Texas', 'Utah', 'California']
In [91]: frame.reindex(columns=states)
Out[91]:
Texas Utah California
a 1 NaN 2
c 4 NaN 5
d 7 NaN 8
一次可以对两个重新索引,可是插值只在行侧(0坐标轴)进行:
frame.reindex(index=['a', 'b', 'c', 'd'], method='ffill',
....: columns=states)
Out:
Texas Utah California
a 1 NaN 2
b 1 NaN 2
c 4 NaN 5
d 7 NaN 8
使用带标签索引的 ix 可以把重新索引做的更简单:
frame.ix[['a', 'b', 'c', 'd'], states]
Out:
Texas Utah California
a 1 NaN 2
b NaN NaN NaN
c 4 NaN 5
d 7 NaN 8
reindex 函数的参数
参数 | 说明 |
---|---|
index | 作为索引的新序列。可以是索引实例或任何类似序列的Python数据结构。一个索引被完全使用,没有任何拷贝。 |
method | 插值(填充)方法,见上表。 |
fill_value | 代替重新索引时引入的缺失数据值 |
limit | 当前向或后向填充时,最大的填充间隙 |
level | 在多层索引上匹配简单索引,否则选择一个子集 |
copy | 如果新索引与就的相等则底层数据不会拷贝。默认为True(即始终拷贝) |
丢弃指定轴上的项
从坐标轴删除一个多或多个条目是很容易的,如果你有一个索引数组或列表且没有这些条目,但是这可能需要一点修改和集合逻辑。 drop 方法将会返回一个新的对象并从坐标轴中删除指定的一个或多个值:
obj = Series(np.arange(5.), index=['a', 'b', 'c', 'd', 'e'])
new_obj = obj.drop('c')
new_obj
Out:
a 0
b 1
d 3
e 4
obj.drop(['d', 'c'])
Out:
a 0
b 1
e 4
对于DataFrame,可以从任何坐标轴删除索引值。如 data.drop('a',axis = 0)。
索引、选取和过滤
Series索引( obj[...] )的工作原理类似与NumPy索引,除了可以使用Series的索引值,也可以仅使用整数来索引。使用索引来切片和正常的Python切片并不一样,会包含结束点。
索引DataFrame来检索一个或多个列,可以使用一个单一值或一个序列:
data = DataFrame(np.arange(16).reshape((4, 4)),
.....: index=['Ohio', 'Colorado', 'Utah', 'New York'],
.....: columns=['one', 'two', 'three', 'four'])
data
Out:
one two three four
Ohio 0 1 2 3
Colorado 4 5 6 7
Utah 8 9 10 11
New York 12 13 14 15
data['two'] data[['three', 'one']]
Out: Out:
Ohio 1 three one
Colorado 5 Ohio 2 0
Utah 9 Colorado 6 4
New York 13 Utah 10 8
Name: two New York 14 12
可以通过切片或一个布尔数组来选择行:
data[:2] data[data['three'] > 5]
Out: Out:
one two three four one two three four
Ohio 0 1 2 3 Colorado 4 5 6 7
Colorado 4 5 6 7 Utah 8 9 10 11
New York 12 13 14 15
在索引中使用一个布尔DataFrame,例如通过纯量比较产生的:
data < 5
| one | two | three | four
--- | --- | --- | --- | ---
Ohio | True | True | True | True
Colorado | True | False | False | False
Utah | False | False | False | False
New York | False | False | False | False
索引字段 ix 可以从DataFrame选择一个行和列的子集,使用像NumPy的记法再加上轴标签。
data.ix['Colorado',['two','three']] # 或使用 data.ix['Colorado',[1,2]]
Out:
two 5
three 6
Name: Colorado
data.ix[:'Utah','two']
Out:
Ohio 0
Colorado 5
Utah 9
Name: two
data.ix[data.three > 5, :3]
Out:
one two three
Colorado 4 5 6
Utah 8 9 10
New York 12 13 14
DataFrame 的索引选项
类型 | 说明 |
---|---|
obj[val] | 从DataFrame选择单一列或连续列。特殊情况下的便利:布尔数组(过滤行),切片(行切片),或布尔DataFrame(根据条件设置值)。 |
obj.ix[val] | 从DataFrame的行集选择单行 |
obj.ix[:, val] | 从列集选择单列 |
obj.ix[val1, val2] | 选择行和列 |
reindex 方法 | 转换一个或多个轴到新的索引 |
xs 方法 | 通过标签选择单行或单列到一个Series |
icol, irow 方法 | 通过整数位置,分别的选择单行或单列到一个Series |
get_value, set_value 方法 | 通过行和列标选择一个单值 |
算术运算和数据对齐
pandas的最重要的特性之一是在具有不同索引的对象间进行算术运算的行为。当把对象加起来时,如果有任何的索引对不相同的话,在结果中将会把各自的索引联合起来。内部数据对其,在索引不重合的地方引入了NA值。
在算术方法中填充值
在不同索引对象间的算术运算,当一个轴标签在另一个对象中找不到时,你可能想要填充一个特定的值,如0:
df1 = DataFrame(np.arange(12).reshape((3,4)),columns=list('abcd'))
df2 = DataFrame(np.arange(20).reshape((4,5)),columns=list('abcde'))
df1 + df2
把它们加起来导致在不重合的位置出现NA值:
| a | b | c | d | e
--- | --- | --- | --- | --- | ---
0 | 0 | 2 | 4 | 6 | NaN
1 | 9 | 11 | 13 | 15 | NaN
2 | 18 | 20 | 22 | 24 | NaN
3 | NaN | NaN | NaN | NaN | NaN
在 df1 上使用 add 方法,我把 df2 传递给它并给 fill_value 赋了一个参数:
df1.add(df2,fill_value=0)
| a | b | c | d | e
--- | --- | --- | --- | --- | ---
0 | 0 | 2 | 4 | 6 | 4
1 | 9 | 11 | 13 | 15 | 9
2 | 18 | 20 | 22 | 24 | 14
3 | 15 | 16 | 17 | 18 | 19
灵活的算术方法
方法 | 说明 |
---|---|
add | 加法(+) |
sub | 减法(-) |
div | 除法(/) |
mul | 乘法(*) |
DataFrame 和 Series 之间的运算
DataFrame和Series间的算术运算Series的索引将匹配DataFrame的列,并在行上扩展。如果一个索引值在DataFrame的列和Series的索引里都找不着,对象将会从它们的联合重建索引。如果想在行上而不是列上进行扩展,你要使用一个算术方法。例如:
frame = DataFrame(np.arange(12.).reshape((4, 3)), columns=list('bde'),
index=['Utah', 'Ohio', 'Texas', 'Oregon'])
frame
| b | d | e
--- | --- | --- | ---
Utah | 0 | 1 | 2
Ohio | 3 | 4 | 5
Texas | 6 | 7 | 8
Oregon | 9 | 10 | 11
series = frame['d']
frame.sub(series, axis=0)
| b | d | e
--- | --- | --- | ---
Utah | -1 | 0 | 1
Ohio | -1 | 0 | 1
Texas | -1 | 0 | 1
Oregon | -1 | 0 | 1
函数应用和映射
NumPy 的 ufuncs(元素级数组方法)也可以用于操作 pandas 对象:
frame = DataFrame(np.random.randn(4, 3), columns=list('bde'),
index=['Utah', 'Ohio', 'Texas', 'Oregon'])
frame
Out:
b d e
Utah -0.204708 0.478943 -0.519439
Ohio -0.555730 1.965781 1.393406
Texas 0.092908 0.281746 0.769023
Oregon 1.246435 1.007189 -1.296221
np.abs(frame) # frame 的元素的绝对值
Out:
b d e
Utah 0.204708 0.478943 0.519439
Ohio 0.555730 1.965781 1.393406
Texas 0.092908 0.281746 0.769023
Oregon 1.246435 1.007189 1.296221
将函数应用到由各列或行所形成的一维数组上。DataFrame 的 apply 方法既可以实现此功能:
f = lambda x: x.max() - x.min()
frame.apply(f)
Out:
b 1.802165
d 1.684034
e 2.689627
dtype: float64
frame.apply(f, axis=1)
Out:
Utah 0.998382
Ohio 2.521511
Texas 0.676115
Oregon 2.542656
dtype: float64
许多最为常见的数组统计方法都被实现成 DataFrame 方法(如 sum 和 mean),因此无须使用 apply 方法。
除标量值外,传递给 apply 的函数还可以返回由多个值组成的 Series:
def f(x):
return Series([x.min(), x.max()], index=['min', 'max'])
frame.apply(f)
Out:
b d e
min -0.555730 0.281746 -1.296221
max 1.246435 1.965781 1.393406
此外,元素级的 Python 函数也是可以用的。要得到 frame 中各个浮点值的格式化字符串,使用 applymap (之所以叫 applymap ,是因为 Series 有一个用于应用元素级函数的 map 方法)即可:
format = lambda x: '%.2f' % x
frame.applymap(format)
Out:
b d e
Utah -0.20 0.48 -0.52
Ohio -0.56 1.97 1.39
Texas 0.09 0.28 0.77
Oregon 1.25 1.01 -1.30
frame['e'].map(format)
Out:
Utah -0.52
Ohio 1.39
Texas 0.77
Oregon -1.30
Name: e, dtype: object
排序和排名
根据条件对数据集排序(sorting)也是一种重要的内置运算。
对 Series 用sort_index方法排序:
obj = Series(range(4), index=['d', 'a', 'b', 'c'])
obj.sort_index()
Out:
a 1
b 2
c 3
d 0
dtype: int64
对于 DataFrame,则可以根据任意一个轴上的索引进行排序:
frame = DataFrame(np.arange(8).reshape((2, 4)), index=['three', 'one'],
columns=['d', 'a', 'b', 'c'])
frame.sort_index()
Out:
d a b c
one 4 5 6 7
three 0 1 2 3
数据默认是生序排序的,但也可以将序排序:
frame.sort_index(axis=1, ascending=False)
Out:
d c b a
three 0 3 2 1
one 4 7 6 5
按值对 Series 进行排序,可以使用 order 方法:
obj = Series([4, 7, -3, 2])
obj.order()
Out:
2 -3
3 2
0 4
1 7
dtype: int64
在 DataFrame 上,可以根据一个或多个列中的值进行排序,将一个或多个列的名字传递给 by 选项即可:
frame = DataFrame({'b': [4, 7, -3, 2], 'a': [0, 1, 0, 1]})
frame.sort_index(by=['a', 'b'])
Out:
a b
2 0 -3
0 0 4
3 1 2
1 1 7
排名跟排序关系密切,且它会增设一个排名值(从1开始,一直到数组中有效数据的数量)。它跟 numpy.argsort 产生的间接排序索引差不多,只不过它可以根据某种规则破坏平级关系。
默认情况下,rank 是通过“为各组分配一个平均排名”的方式破坏平级关系:
obj = Series([7, -5, 7, 4, 2, 0, 4])
obj.rank()
Out:
0 6.5
1 1.0
2 6.5
3 4.5
4 3.0
5 2.0
6 4.5
dtype: float64
也可以根据值在原数据中出现的顺序给出排名:
obj.rank(method='first')
Out:
0 6
1 1
2 7
3 4
4 3
5 2
6 5
dtype: float64
排名时用于破坏平级关系的 method 选项
method | 说明 |
---|---|
average | 默认:在相等分组中,为各个值分配平均排名 |
min | 使用整个分组的最小排名 |
max | 使用整个分组的最大排名 |
first | 按值在原始数据中的出现吮吸分配排名 |
带有重复值的轴索引
索引的 is_unique 属性可以查看索引值是否唯一。
如果某个索引对应多个值,则返回一个 Series;而对应单个值得,则返回一个标量值。对 DataFrame 的行进行索引时也是如此。
汇总和计算描述统计
pandas 对象拥有一组常用的数学和统计方法。它们大部分都属于约简和汇总统计,用于从 Series 中提取单个值(如 sum 或 mean)或从 DataFrame 的行货列中提取一个 Series。跟对应的 Numpy 数组方法相比,它们都是基于没有缺失数据的假设而构建的。
描述和汇总统计
方法 | 说明 |
---|---|
count | 非 NA 值的数量 |
describe | 针对 Series 或 DataFrame 的列计算汇总统计 |
min , max | 最小值和最大值 |
argmin , argmax | 最小值和最大值的索引位置(整数) |
idxmin , idxmax | 最小值和最大值的索引值 |
quantile | 样本分位数(0 到 1) |
sum | 求和 |
mean | 均值 |
median | 中位数 |
mad | 根据均值计算平均绝对离差 |
var | 方差 |
std | 标准差 |
skew | 样本值的偏度(三阶矩) |
kurt | 样本值的峰度(四阶矩) |
cumsum | 样本值的累计和 |
cummin , cummax | 样本值的累计最大值和累计最小值 |
cumprod | 样本值的累计积 |
diff | 计算一阶差分(对时间序列很有用) |
pct_change | 计算百分数变化 |
相关系数和协方差
Series 的 corr 和 cov 方法用于计算两个 Series 中重叠的、非NA的、按索引对齐的值得相关系数和协方差。
DataFrame 的 corr 和 cov 方法将以 DataFrame 的形式返回完整的相关系数或协方差矩阵。
DataFrame 的 corrwith 方法可以计算其列或行跟另一个 Series 或 DataFrame 之间的相关系数。
唯一值、值计算以及成员资格
唯一值、值计数和成员资格方法
方法 | 说明 |
---|---|
isin | 计算一个表示“Series 各值是否包含于传入的值序列中”的布尔型数组 |
unique | 计算 Series 中的唯一值数组,按发现的顺序返回 |
value_counts | 返回一个 Series,其索引为唯一值,其值为计数,降序排列 |
将pandas.value_counts 传给 DataFrame 的 apply 函数:
data = DataFrame({'Qu1': [1, 3, 4, 3, 4],
'Qu2': [2, 3, 1, 2, 3],
'Qu3': [1, 5, 2, 4, 4]})
data
Out:
Qu1 Qu2 Qu3
0 1 2 1
1 3 3 5
2 4 1 2
3 3 2 4
4 4 3 4
result = data.apply(pd.value_counts).fillna(0)
result
Out:
Qu1 Qu2 Qu3
1 1 1 1
2 0 2 1
3 2 2 0
4 2 0 2
5 0 0 1
处理缺失数据
NA 处理方法
方法 | 说明 |
---|---|
dropna | 根据各标签的值中是否存在缺失数据对轴标签进行过滤,可通过阀值调节对缺失值的容忍度 |
fillna | 用指定值或插值方法(如 ffill 或 bfill)填充缺失数据 |
isnull | 返回一个含有布尔值得对象,这些布尔值表示哪些值是缺失值,该对象的类型与源类型一样 |
notnull | isnull的否定式 |
滤除缺失数据
对于 DataFrame 对象,dropna 默认丢弃任何含有缺失值的行:
data = DataFrame([[1., 6.5, 3.], [1., NA, NA],
[NA, NA, NA], [NA, 6.5, 3.]])
cleaned = data.dropna()
data
Out:
0 1 2
0 1 6.5 3
1 1 NaN NaN
2 NaN NaN NaN
3 NaN 6.5 3
cleaned
Out:
0 1 2
0 1 6.5 3
传入 how = 'all' 将只丢弃全为 NA 的那些行:
data.dropna(how='all')
Out:
0 1 2
0 1 6.5 3
1 1 NaN NaN
3 NaN 6.5 3
填充缺失数据
fillna 方法是主要的填充函数。
通过一个字典调用 fillna,可以实现对不同的列填充不同的值:
df = DataFrame(np.random.randn(7, 3))
df.ix[:4, 1] = NA; df.ix[:2, 2] = NA
df
Out:
0 1 2
0 0.274992 NaN NaN
1 0.886429 NaN NaN
2 1.669025 NaN NaN
3 0.476985 NaN -1.021228
4 -0.577087 NaN 0.302614
5 0.523772 0.000940 1.343810
6 -0.713544 -0.831154 -2.370232
df.fillna({1: 0.5, 3: -1})
Out:
0 1 2
0 0.274992 0.500000 NaN
1 0.886429 0.500000 NaN
2 1.669025 0.500000 NaN
3 0.476985 0.500000 -1.021228
4 -0.577087 0.500000 0.302614
5 0.523772 0.000940 1.343810
6 -0.713544 -0.831154 -2.370232
fillna 函数的参数
参数 | 说明 |
---|---|
value | 用于填充缺失值的标量值或字典对象 |
method | 插值方式。如果函数调用时未指定其他参数的话,默认为“ffill” |
axis | 待填充的轴,默认axis = 0 |
inplace | 修改调用者对象而不产生副本 |
limit | 可以连续填充的最大数量 |
层次化索引
层次化索引时 pandas 的一项重要功能,它是你能在一个轴上拥有多个索引级别。
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
Out:
a 1 -0.204708
2 0.478943
3 -0.519439
b 1 -0.555730
2 1.965781
3 1.393406
c 1 0.092908
2 0.281746
d 2 0.769023
3 1.246435
dtype: float64
data.index
Out:
MultiIndex(levels=[[u'a', u'b', u'c', u'd'], [1, 2, 3]],
labels=[[0, 0, 0, 1, 1, 1, 2, 2, 3, 3], [0, 1, 2, 0, 1, 2, 0, 1, 1, 2]])
层次化索引在数据重塑和基于分组的操作(如透视表生成)中扮演着重要角色。如 data 可以通过其 unstack 方法被重新安排到一个 DataFrame 中:
data.unstack()
Out:
1 2 3
a -0.204708 0.478943 -0.519439
b -0.555730 1.965781 1.393406
c 0.092908 0.281746 NaN
d NaN 0.769023 1.246435
# unstack 的逆运算是 stack。
对于一个 DataFrame,每条轴都可以有分层索引:
frame = DataFrame(np.arange(12).reshape((4, 3)),
index=[['a', 'a', 'b', 'b'], [1, 2, 1, 2]],
columns=[['Ohio', 'Ohio', 'Colorado'],
['Green', 'Red', 'Green']])
frame.index.names = ['key1', 'key2']
frame.columns.names = ['state', 'color']
frame
Out:
state Ohio Colorado
color Green Red Green
key1 key2
a 1 0 1 2
2 3 4 5
b 1 6 7 8
2 9 10 11
重排分级顺序
swaplevel 接受两个级别编号或名称,并返回一个互换了级别的新对象:
frame.swaplevel('key1', 'key2')
Out:
state Ohio Colorado
color Green Red Green
key2 key1
1 a 0 1 2
2 a 3 4 5
1 b 6 7 8
2 b 9 10 11
sortlevel 根据单个级别中的值对数据进行排序。
frame.swaplevel(0, 1).sortlevel(0)
Out:
state Ohio Colorado
color Green Red Green
key2 key1
1 a 0 1 2
b 6 7 8
2 a 3 4 5
b 9 10 11
根据级别汇总统计
许多对 DataFrame 和 Series 的描述和汇总统计都有一个 level 选项,它用于指定某条周上求和的级别。
frame.sum(level='color', axis=1)
Out:
color Green Red
key1 key2
a 1 2 1
2 8 4
b 1 14 7
2 20 10
# 这其实利用了 pandas 的 groupby 功能。
使用 DataFrame 的列
DataFrame 的 set_index 函数可以将 DataFrame 的一个或多个列当做行索引来用,而 reset_index 函数则是将行索引变成 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
Out:
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
frame2 = frame.set_index(['c', 'd']) # 可以加入参数 drop=False 保留数据中的c、d列。
frame2
Out:
a b
c d
one 0 0 7
1 1 6
2 2 5
two 0 3 4
1 4 3
2 5 2
3 6 1
frame2.reset_index()
Out:
c d a b
0 one 0 0 7
1 one 1 1 6
2 one 2 2 5
3 two 0 3 4
4 two 1 4 3
5 two 2 5 2
6 two 3 6 1
其他有关 pandas 的话题
整数索引
操作由整数索引的 pandas 对象跟内置的 Python 数据结构(如列表和元组)在索引语义上有些不同。例如:
ser = Series(np.arange(3.))
ser[-1]
==会产生错误。==
对于一个非整数索引,就没有问题。为了保持良好的一致性,尽量保持操作时面向标签的,同样包括用 ix 进行切片。如果需要可靠的、不考虑索引类型的、基于位置的索引,可以使用 Series 的 iloc 或 iat 方法和 DataFrame 的 irow 和 icol 方法:
ser.iloc[-1]
Out:
2.0
frame = DataFrame(np.arange(6).reshape((3, 2)), index=[2, 0, 1])
frame.iloc[0]
Out:
0 0
1 1
Name: 2, dtype: int32
面板数据
pandas 有一个 Panel 数据结构,可以将其看作一个三维版的 DataFrame。pandas 的大部分开发工作都集中在表格型数据上,所以这些事数据更常见。