pandas

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 的大部分开发工作都集中在表格型数据上,所以这些事数据更常见。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容