https://www.cnblogs.com/chaosimple/p/4153083.html
起步
Pandas最初被作为金融数据分析工具而开发出来,因此 pandas 为时间序列分析提供了很好的支持。 Pandas 的名称来自于面板数据(panel data)和python数据分析 (data analysis) 。panel data是经济学中关于多维数据集的一个术语,在Pandas中也提供了panel的数据类型。
在我看来,对于 Numpy 以及 Matplotlib ,Pandas可以帮助创建一个非常牢固的用于数据挖掘与分析的基础。而Scipy当然是另一个主要的也十分出色的科学计算库。
安装与导入
通过pip进行安装: pip install pandas
导入:
1
|
import
pandas as pd
|
Pandas的数据类型
Pandas基于两种数据类型: series 与 dataframe 。
Series
一个series是一个一维的数据类型,其中每一个元素都有一个标签。类似于Numpy中元素带标签的数组。其中,标签可以是数字或者字符串。
1
2
3
4
5
6
|
# coding: utf-8
import
numpy as np
import
pandas as pd
s
=
pd.Series([
1
,
2
,
5
, np.nan,
6
,
8
])
print
s
|
输出:
1
2
3
4
5
6
7
|
0
1.0
1
2.0
2
5.0
3
NaN
4
6.0
5
8.0
dtype: float64
|
DataFrame
一个dataframe是一个二维的表结构。Pandas的dataframe可以存储许多种不同的数据类型,并且每一个坐标轴都有自己的标签。你可以把它想象成一个series的字典项。
创建一个 DateFrame:
1
2
3
4
5
|
#创建日期索引序列
dates
=
pd.date_range(
'20130101'
, periods
=
6
)
#创建Dataframe,其中 index 决定索引序列,columns 决定列名
df
=
pd.DataFrame(np.random.randn(
6
,
4
), index
=
dates, columns
=
list
(
'ABCD'
))
print
df
|
输出:
1
2
3
4
5
6
7
|
A B C D
2013
-
01
-
01
-
0.334482
0.746019
-
2.205026
-
0.803878
2013
-
01
-
02
2.007879
1.559073
-
0.527997
0.950946
2013
-
01
-
03
-
1.053796
0.438214
-
0.027664
0.018537
2013
-
01
-
04
-
0.208744
-
0.725155
-
0.395226
-
0.268529
2013
-
01
-
05
0.080822
-
1.215433
-
0.785030
0.977654
2013
-
01
-
06
-
0.126459
0.426328
-
0.474553
-
1.968056
|
字典创建 DataFrame
1
2
3
4
5
6
|
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'
})
|
输出:
1
2
3
4
5
|
A B C D E F
0
1
2013
-
01
-
02
1
3
test foo
1
1
2013
-
01
-
02
1
3
train foo
2
1
2013
-
01
-
02
1
3
test foo
3
1
2013
-
01
-
02
1
3
train foo
|
将文件数据导入Pandas
1
2
|
df
=
pd.read_csv(
"Average_Daily_Traffic_Counts.csv"
, header
=
0
)
df.head()
|
数据源可以是 英国政府数据 或 美国政府数据 来获取数据源。当然, Kaggle 是另一个好用的数据源。
选择/切片
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
# 选择单独的一列,返回 Serires,与 df.A 效果相当。
df[
'A'
]
# 位置切片
df[
0
:
3
]
# 索引切片
df[
'20130102'
:
'20130104'
]
# 通过标签选择
df.loc[dates[
0
]]
# 对多个轴同时通过标签进行选择
df.loc[:,[
'A'
,
'B'
]]
# 获得某一个单元的数据
df.loc[dates[
0
],
'A'
]
# 或者
df.at[dates[
0
],
'A'
]
# 速度更快的做法
# 通过位置进行选择
df.iloc[
3
]
# 切片
df.iloc[
3
:
5
,
0
:
2
]
# 列表选择
df.iloc[[
1
,
2
,
4
],[
0
,
2
]]
# 获得某一个单元的数据
df.iloc[
1
,
1
]
# 或者
df.iat[
1
,
1
]
# 更快的做法
# 布尔索引
df[df.A >
0
]
# 获得大于零的项的数值
df[df >
0
]
# isin 过滤
df2[df2[
'E'
].isin([
'two'
,
'four'
])]
|
赋值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
# 新增一列,根据索引排列
s1
=
pd.Series([
1
,
2
,
3
,
4
,
5
,
6
], index
=
pd.date_range(
'20130102'
, periods
=
6
))
df[
'F'
]
=
s1
# 缺省项
# 在 pandas 中使用 np.nan 作为缺省项的值。
df1
=
df.reindex(index
=
dates[
0
:
4
], columns
=
list
(df.columns)
+
[
'E'
])
df1.loc[dates[
0
]:dates[
1
],
'E'
]
=
1
# 删除所有带有缺省项的行
df1.dropna(how
=
'any'
)
# 填充缺省项
df1.fillna(value
=
5
)
# 获得缺省项的布尔掩码
pd.isnull(df1)
|
观察操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
# 观察开头的数据
df.head()
# 观察末尾的数据
df.tail(
3
)
# 显示索引
df.index
# 显示列
df.columns
# 显示底层 numpy 结构
df.values
# DataFrame 的基本统计学属性预览
df.describe()
"""
A B C D
count 6.000000 6.000000 6.000000 6.000000 #数量
mean 0.073711 -0.431125 -0.687758 -0.233103 #平均值
std 0.843157 0.922818 0.779887 0.973118 #标准差
min -0.861849 -2.104569 -1.509059 -1.135632 #最小值
25% -0.611510 -0.600794 -1.368714 -1.076610 #正态分布 25%
50% 0.022070 -0.228039 -0.767252 -0.386188 #正态分布 50%
75% 0.658444 0.041933 -0.034326 0.461706 #正态分布 75%
max 1.212112 0.567020 0.276232 1.071804 #最大值
"""
# 转置
df.T
# 根据某一轴的索引进行排序
df.sort_index(axis
=
1
, ascending
=
False
)
# 根据某一列的数值进行排序
df.sort(columns
=
'B'
)
|
统计
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
# 求平均值
df.mean()
""
"
A
-
0
.
004474
B
-
0
.
383981
C
-
0
.
687758
D
5
.
000000
F
3
.
000000
dtype: float64
""
"
# 指定轴上的平均值
df.mean(
1
)
# 不同维度的 pandas 对象也可以做运算,它会自动进行对应,shift 用来做对齐操作。
s = pd.Series([
1
,
3
,
5
,np.nan,
6
,
8
], index=dates).shift(
2
)
""
"
2013
-
01
-
01
NaN
2013
-
01
-
02
NaN
2013
-
01
-
03
1
2013
-
01
-
04
3
2013
-
01
-
05
5
2013
-
01
-
06
NaN
Freq:
D
, dtype: float64
""
"
# 对不同维度的 pandas 对象进行减法操作
df.sub(s, axis=
'index'
)
""
"
A
B
C
D
F
2013
-
01
-
01
NaN NaN NaN NaN NaN
2013
-
01
-
02
NaN NaN NaN NaN NaN
2013
-
01
-
03
-
1
.
861849
-
3
.
104569
-
1
.
494929
4
1
2013
-
01
-
04
-
2
.
278445
-
3
.
706771
-
4
.
039575
2
0
2013
-
01
-
05
-
5
.
424972
-
4
.
432980
-
4
.
723768
0
-
1
2013
-
01
-
06
NaN NaN NaN NaN NaN
""
"
|
函数应用
1
2
|
# 累加
df.
apply
(np.cumsum)
|
直方图
1
2
3
4
5
6
7
8
9
10
|
s
=
pd.Series(np.random.randint(
0
,
7
, size
=
10
))
s.value_counts()
"""
4 5
6 2
2 2
1 1
dtype: int64
String Methods
"""
|
字符处理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
s
=
pd.Series([
'A'
,
'B'
,
'C'
,
'Aaba'
,
'Baca'
, np.nan,
'CABA'
,
'dog'
,
'cat'
])
s.
str
.lower()
"""
0 a
1 b
2 c
3 aaba
4 baca
5 NaN
6 caba
7 dog
8 cat
dtype: object
"""
|
合并
使用 concat() 连接 pandas 对象:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
df
=
pd.DataFrame(np.random.randn(
10
,
4
))
"""
0 1 2 3
0 -0.548702 1.467327 -1.015962 -0.483075
1 1.637550 -1.217659 -0.291519 -1.745505
2 -0.263952 0.991460 -0.919069 0.266046
3 -0.709661 1.669052 1.037882 -1.705775
4 -0.919854 -0.042379 1.247642 -0.009920
5 0.290213 0.495767 0.362949 1.548106
6 -1.131345 -0.089329 0.337863 -0.945867
7 -0.932132 1.956030 0.017587 -0.016692
8 -0.575247 0.254161 -1.143704 0.215897
9 1.193555 -0.077118 -0.408530 -0.862495
"""
pieces
=
[df[:
3
], df[
3
:
7
], df[
7
:]]
pd.concat(pieces)
"""
0 1 2 3
0 -0.548702 1.467327 -1.015962 -0.483075
1 1.637550 -1.217659 -0.291519 -1.745505
2 -0.263952 0.991460 -0.919069 0.266046
3 -0.709661 1.669052 1.037882 -1.705775
4 -0.919854 -0.042379 1.247642 -0.009920
5 0.290213 0.495767 0.362949 1.548106
6 -1.131345 -0.089329 0.337863 -0.945867
7 -0.932132 1.956030 0.017587 -0.016692
8 -0.575247 0.254161 -1.143704 0.215897
9 1.193555 -0.077118 -0.408530 -0.862495
"""
|
join 合并:
1
2
3
4
5
6
7
8
9
10
|
left
=
pd.DataFrame({
'key'
: [
'foo'
,
'foo'
],
'lval'
: [
1
,
2
]})
right
=
pd.DataFrame({
'key'
: [
'foo'
,
'foo'
],
'rval'
: [
4
,
5
]})
pd.merge(left, right, on
=
'key'
)
"""
key lval rval
0 foo 1 4
1 foo 1 5
2 foo 2 4
3 foo 2 5
"""
|
追加
在 dataframe 数据后追加行
1
2
3
|
df
=
pd.DataFrame(np.random.randn(
8
,
4
), columns
=
[
'A'
,
'B'
,
'C'
,
'D'
])
s
=
df.iloc[
3
]
df.append(s, ignore_index
=
True
)
|
分组
分组常常意味着可能包含以下的几种的操作中一个或多个
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
df
=
pd.DataFrame({
'A'
: [
'foo'
,
'bar'
,
'foo'
,
'bar'
,
'foo'
,
'bar'
,
'foo'
,
'foo'
],
'B'
: [
'one'
,
'one'
,
'two'
,
'three'
,
'two'
,
'two'
,
'one'
,
'three'
],
'C'
: np.random.randn(
8
),
'D'
: np.random.randn(
8
)})
# 对单个分组应用函数,数据被分成了 bar 组与 foo 组,分别计算总和。
df.groupby(
'A'
).
sum
()
# 依据多个列分组会构成一个分级索引
df.groupby([
'A'
,
'B'
]).
sum
()
"""
C D
A B
bar one -1.814470 2.395985
three -0.595447 0.166599
two -0.392670 -0.136473
foo one -1.195665 -0.616981
three 1.928123 -1.623033
two 2.414034 1.600434
"""
|
数据透视表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
df
=
pd.DataFrame({
'A'
: [
'one'
,
'one'
,
'two'
,
'three'
]
*
3
,
'B'
: [
'A'
,
'B'
,
'C'
]
*
4
,
'C'
: [
'foo'
,
'foo'
,
'foo'
,
'bar'
,
'bar'
,
'bar'
]
*
2
,
'D'
: np.random.randn(
12
),
'E'
: np.random.randn(
12
)})
# 生成数据透视表
pd.pivot_table(df, values
=
'D'
, index
=
[
'A'
,
'B'
], columns
=
[
'C'
])
"""
C bar foo
A B
one A -0.773723 1.418757
B -0.029716 -1.879024
C -1.146178 0.314665
three A 1.006160 NaN
B NaN -1.035018
C 0.648740 NaN
two A NaN 0.100900
B -1.170653 NaN
C NaN 0.536826
"""
|
时间序列
pandas 拥有既简单又强大的频率变换重新采样功能,下面的例子从 1次/秒 转换到了 1次/5分钟:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
rng
=
pd.date_range(
'1/1/2012'
, periods
=
100
, freq
=
'S'
)
ts
=
pd.Series(np.random.randint(
0
,
500
,
len
(rng)), index
=
rng)
ts.resample(
'5Min'
, how
=
'sum'
)
"""
2012-01-01 25083
Freq: 5T, dtype: int32
"""
# 本地化时区表示
rng
=
pd.date_range(
'3/6/2012 00:00'
, periods
=
5
, freq
=
'D'
)
ts
=
pd.Series(np.random.randn(
len
(rng)), rng)
"""
2012-03-06 0.464000
2012-03-07 0.227371
2012-03-08 -0.496922
2012-03-09 0.306389
2012-03-10 -2.290613
Freq: D, dtype: float64
"""
ts_utc
=
ts.tz_localize(
'UTC'
)
"""
2012-03-06 00:00:00+00:00 0.464000
2012-03-07 00:00:00+00:00 0.227371
2012-03-08 00:00:00+00:00 -0.496922
2012-03-09 00:00:00+00:00 0.306389
2012-03-10 00:00:00+00:00 -2.290613
Freq: D, dtype: float64
"""
# 转换为周期
ps
=
ts.to_period()
# 转换为时间戳
ps.to_timestamp()
|
分类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
df
=
pd.DataFrame({
"id"
:[
1
,
2
,
3
,
4
,
5
,
6
],
"raw_grade"
:[
'a'
,
'b'
,
'b'
,
'a'
,
'a'
,
'e'
]})
# 将 raw_grades 转换成 Categoricals 类型
df[
"grade"
]
=
df[
"raw_grade"
].astype(
"category"
)
df[
"grade"
]
"""
0 a
1 b
2 b
3 a
4 a
5 e
Name: grade, dtype: category
Categories (3, object): [a, b, e]
"""
# 重命名分类
df[
"grade"
]
=
df[
"grade"
].cat.set_categories([
"very bad"
,
"bad"
,
"medium"
,
"good"
,
"very good"
])
# 根据分类的顺序对数据进行排序
df.sort(
"grade"
)
"""
id raw_grade grade
5 6 e very bad
1 2 b good
2 3 b good
0 1 a very good
3 4 a very good
4 5 a very good
"""
|
作图
1
2
3
|
ts
=
pd.Series(np.random.randn(
1000
), index
=
pd.date_range(
'1/1/2000'
, periods
=
1000
))
ts
=
ts.cumsum()
ts.plot()
|
数据IO
1
2
3
4
5
6
7
8
9
10
11
|
# 从 csv 文件读取数据
pd.read_csv(
'foo.csv'
)
# 保存到 csv 文件
df.to_csv(
'foo.csv'
)
# 读取 excel 文件
pd.read_excel(
'foo.xlsx'
,
'Sheet1'
, index_col
=
None
, na_values
=
[
'NA'
])
# 保存到 excel 文件
df.to_excel(
'foo.xlsx'
, sheet_name
=
'Sheet1'
)
|
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家学习或者使用python能带来一定的帮助,如果有疑问大家可以留言交流。
原文链接:http://www.hongweipeng.com/index.php/archives/1105/?utm_source=tuicool&utm_medium=referral