机器学习基础3--python科学计算pandas(上)

利用python进行科学计算,numpy和pandas这两个库是必不可少的。

上一篇介绍了numpy,本篇介绍pandas

如果用 python 的列表和字典来作比较, 那么可以说 Numpy 是列表形式的,没有数值标签,而 Pandas 就是字典形式。Pandas是基于Numpy构建的,让Numpy为中心的应用变得更加简单。

要使用pandas,首先需要了解他主要两个数据结构:Series和DataFrame。

pandas 导入

省略下载和安装,代码中导入pandas

1
import nupandaspy as pd

Series

1
2
3
4
5
6
7
8
9
10
11
12
s = pd.Series([1,3,6,np.nan,44,1])

print(s)
"""
0 1.0
1 3.0
2 6.0
3 NaN
4 44.0
5 1.0
dtype: float64
"""

打印的内容,左边是索引,右边的值。由于我们没有为数据指定索引。于是会自动创建一个0到N-1(N为长度)的整数型索引.

DataFrame

DataFrame是一个表格型的数据结构.它包含有一组有序的列,每列可以是不同的值类型(数值,字符串,布尔值等)。DataFrame既有行索引也有列索引, 它可以被看做由Series组成的大字典。

1
2
3
4
5
6
7
# 这里我们用map字典结构去初始化一个DataFrame
df2 = pd.DataFrame({'A': 1.,
'B': pd.Timestamp('20130102'),
'C': pd.Series(1, index=list(range(4)), dtype='float32'),
'D': np.array([3] * 4, dtype='int32'),
'E': pd.Categorical(["test", "train", "test", "train"]),
'F': 'foo'})

让我们分别看一下输出

基本操作

打印DataFrame

1
print(df2)
     A          B    C  D      E    F
0  1.0 2013-01-02  1.0  3   test  foo
1  1.0 2013-01-02  1.0  3  train  foo
2  1.0 2013-01-02  1.0  3   test  foo
3  1.0 2013-01-02  1.0  3  train  foo

查询每一列的type

1
print(df2.dtypes)
A           float64
B    datetime64[ns]
C           float32
D             int32
E          category
F            object
dtype: object

查看行号

1
print(df2.index)
Int64Index([0, 1, 2, 3], dtype='int64')

查看列的名称

1
print(df2.index)
Index(['A', 'B', 'C', 'D', 'E', 'F'], dtype='object')

只查看值

1
print(df2.values)
[[1.0 Timestamp('2013-01-02 00:00:00') 1.0 3 'test' 'foo']
[1.0 Timestamp('2013-01-02 00:00:00') 1.0 3 'train' 'foo']
[1.0 Timestamp('2013-01-02 00:00:00') 1.0 3 'test' 'foo']
[1.0 Timestamp('2013-01-02 00:00:00') 1.0 3 'train' 'foo']]

查看描述

1
print(df2.describe())
         A    C    D
count  4.0  4.0  4.0
mean   1.0  1.0  3.0
std    0.0  0.0  0.0
min    1.0  1.0  3.0
25%    1.0  1.0  3.0
50%    1.0  1.0  3.0
75%    1.0  1.0  3.0
max    1.0  1.0  3.0

转置

1
print(df2.T)

这里输出就省略了

索引排序

1
2
#axis=0按照列名排序,axis=1按照行名排序 按照降序排序
print(df2.sort_index(axis=1, ascending=False))
     F      E  D    C          B    A
0  foo   test  3  1.0 2013-01-02  1.0
1  foo  train  3  1.0 2013-01-02  1.0
2  foo   test  3  1.0 2013-01-02  1.0
3  foo  train  3  1.0 2013-01-02  1.0

值排序

1
2
# 指定按照某个列名排序
print(df2.sort_values(by='B'))

筛选

首先我们新建一个DataFrame数据

1
2
dates = pd.date_range('20130101', periods=6)
df = pd.DataFrame(np.arange(24).reshape((6,4)),index=dates, columns=['A','B','C','D'])

“””
A B C D
2013-01-01 0 1 2 3
2013-01-02 4 5 6 7
2013-01-03 8 9 10 11
2013-01-04 12 13 14 15
2013-01-05 16 17 18 19
2013-01-06 20 21 22 23
“””

指定筛选具体的列名

1
2
3
4
5
6
7
8
9
10
11
12
13
print(df['A'])  # 类似map中通过key取值
print(df.A) # 类似A是df的一个属性

#输出都是一样的,会输出行名为『A』的列及行名
"""
2013-01-01 0
2013-01-02 4
2013-01-03 8
2013-01-04 12
2013-01-05 16
2013-01-06 20
Freq: D, Name: A, dtype: int64
"""

筛选多行or多列

1
2
3
4
5
6
7
8
print(df[0:3])
#输出0,1,2三行,这里的[0:3]不包括第3行,例如df[1:1]返回的就是一个空对象
"""
A B C D
2013-01-01 0 1 2 3
2013-01-02 4 5 6 7
2013-01-03 8 9 10 11
"""
1
2
3
4
5
6
7
8
# 这样写相当于一个闭区间
print(df['20130102':'20130104'])
"""
A B C D
2013-01-02 4 5 6 7
2013-01-03 8 9 10 11
2013-01-04 12 13 14 15
"""

通过判断

1
2
3
4
5
6
7
print(df[df.A>8])
"""
A B C D
2013-01-04 12 13 14 15
2013-01-05 16 17 18 19
2013-01-06 20 21 22 23
"""

根据标签 loc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 根据行标签(loc第一个参数,只能用于行标签)
print(df.loc['20130102'])
# print(df['20130102']) 这样是不可以的,会报错
"""
A 4
B 5
C 6
D 7
Name: 2013-01-02 00:00:00, dtype: int64
"""
#第二个参数筛选列名称
print(df.loc[:,['A','B']])
"""
A B
2013-01-01 0 1
2013-01-02 4 5
2013-01-03 8 9
2013-01-04 12 13
2013-01-05 16 17
2013-01-06 20 21
"""

根据序列 iloc

iloc第一个参数过滤行,第二个参数过滤列

1
2
3
4
5
6
7
8
print(df.iloc[[1,3,5],1:3])
"""
B C
2013-01-02 5 6
2013-01-04 13 14
2013-01-06 21 22

"""

根据混合的这两种 ix

前面我们知道,loc可以根据名称过滤,iloc可以根据index位置过滤,那结合这两种过滤方式可以用ix

1
2
3
4
5
6
7
print(df.ix[:3,['A','C']])
"""
A C
2013-01-01 0 2
2013-01-02 4 6
2013-01-03 8 10
"""

设置值

设置值比较简单

1
2
3
4
5
6
df.iloc[2,2] = 1111
df.loc['20130101','B'] = 2222
df.B[df.A>4] = 0
df['F'] = np.nan
# 插入一行
df['E'] = pd.Series([1,2,3,4,5,6], index=pd.date_range('20130101',periods=6))

处理丢失数据

1
2
3
4
df.dropna(
axis=0, # 0: 对行进行操作; 1: 对列进行操作
how='any' # 'any': 只要存在 NaN 就 drop 掉; 'all': 必须全部是 NaN 才 drop
)

fillna是将 NaN 的值用其他值代替, 比如代替成 0:

1
df.fillna(value=0)

可以通过pd.isnull()判断是否有缺失数据 NaN, 为 True 表示缺失数据

下篇将总结下pandas的数据导入导出,数据合并等。