数据分析工具Pandas(一)

一、Pandas简介

1.什么是Pandas?

Pandas的名称来自于面板数据(panel data)和Python数据分析(data analysis)。
Pandas是一个强大的分析结构化数据的工具集,基于NumPy构建,提供了高级数据结构和数据操作工具,它是使Python成为强大而高效的数据分析环境的重要因素之一。
一个强大的分析和操作大型结构化数据集所需的工具集,基础是NumPy,提供了高性能矩阵的运算,提供了大量能够快速便捷地处理数据的函数和方法
应用于数据挖掘,数据分析,提供数据清洗功能。http://pandas.pydata.org

2.导入pandas
# pd别名业界约定
>>>import pandas as pd

二、pandas的数据结构

Series

Series是一种类似于一维数组的对象,组成:
一组数据(各种NumPy数据类型),一组与之对应的索引(数据标签),索引(index)在左,数据(values)在右,索引是自动创建的

DataFrame

一个表格型的数据结构,它含有一组有序的列,每列可以是不同类型的值。DataFrame既有行索引也有列索引,数据是以二维结构存放的。类似多维数组/表格数据 (如,excel, R中的data.frame),每列数据可以是不同的类型,索引包括列索引和行索引

1.Series

1-1.通过list构建Series

>>> import pandas as pd
 # 不指定索引的话,默认从0开始
>>> ser_obj=pd.Series(range(10,30))
>>>ser_obj
0     10
1     11
2     12
3     13
4     14
5     15
6     16
7     17
8     18
9     19
10    20
11    21
12    22
13    23
14    24
15    25
16    26
17    27
18    28
19    29
dtype: int64
>>> ser_obj.head(3)   #打印前三行数据
0    10
1    11
2    12
dtype: int64
>>> print(type(ser_obj)) #打印数据类型
<class 'pandas.core.series.Series'>

1-2. 通过dict构建Series

>>> dict = {1000:"hello",2000:"world",3000:"!"}
>>> ser_obj = pd.Series(dict)
>>> print(ser_obj)
1000    hello
2000    world
3000        !
dtype: object

1-3.获取数据和索引
ser_obj.index 和 ser_obj.values

# 获取数据 
>>> print(ser_obj.values)
['hello' 'world' '!']
# 获取索引
>>> print(ser_obj.index)
Int64Index([1000, 2000, 3000], dtype='int64')

1-4. 通过索引获取数据
ser_obj[idx]

#通过索引获取数据 
>>> print(ser_obj[1000])
hello
>>> print(ser_obj[2000])
world

1-5. 设置名称
对象名:ser_obj.name 给整个表取名字
对象索引名:ser_obj.index.name 给某一列

>>> ser_obj.name = 'presidential_polls'
>>> ser_obj.index.name = 'adjpoll_trump'
>>> print(ser_obj.head())
adjpoll_trump
1000    hello
2000    world
3000        !
Name: presidential_polls, dtype: object

2.DataFrame

2-1. 通过darray构建DataFrame

>>> arr_obj = np.random.rand(3,4)
>>> df_obj = pd.DataFrame(arr_obj)
>>> print(df_obj)
          0         1         2         3
0  0.471906  0.210490  0.781181  0.215866
1  0.293406  0.387063  0.961384  0.935796
2  0.761027  0.038050  0.759989  0.831180
>>> print(df_obj.head(2))  # 查看前两行
          0         1         2         3
0  0.471906  0.210490  0.781181  0.215866
1  0.293406  0.387063  0.961384  0.935796

2-2. 通过dict构建DataFrame

>>> dict = {
...     "A":1,
...     "B":pd.Timestamp("20171212"),
...     "C":pd.Series(range(10,14),dtype="float64"),
...     "D":["python","java","c++","c"],
...     "E":np.array([3] *4,dtype="int32"),
...     "F":"Lyh"
... }
>>> df_obj = pd.DataFrame(dict)
>>> print(df_obj)
   A          B     C       D  E     F
0  1 2017-12-12  10.0  python  3  Lyh
1  1 2017-12-12  11.0    java  3  Lyh
2  1 2017-12-12  12.0     c++  3  Lyh
3  1 2017-12-12  13.0       c  3  Lyh

2-3. 通过列索引获取列数据
df_obj[col_idx] 或 df_obj.col_idx

>>> print(df_obj['A'])
0    1
1    1
2    1
3    1
Name: A, dtype: int64
>>> print(type(df_obj['A']))
<class 'pandas.core.series.Series'>
>>> print(df_obj.A)
0    1
1    1
2    1
3    1
Name: A, dtype: int64

dataframe数据访问

#通过索引,先列后行
>>> print(df_obj['D'][0])
python
#查找指定元素,先找列,在找行
>>> print(df_obj.D[2])
c++

2-4. 增加列数据
df_obj[new_col_idx] = data
类似Python的 dict添加key-value

>>> df_obj["G"] = "呵呵"
>>> print(df_obj)
   A          B     C       D  E     F   G
0  1 2017-12-12  10.0  python  3  Lyh 呵呵
1  1 2017-12-12  11.0    java  3  Lyh 呵呵
2  1 2017-12-12  12.0     c++  3  Lyh 呵呵
3  1 2017-12-12  13.0       c  3  Lyh 呵呵

df_obj[new_col_idx] = data
类似Python的 dict添加key-value

#新增一列,数据可以是dataFrame对象的其他列运算后的结果,例如,添加H列,C的值加10
>>> df_obj["H"] = df_obj["C"]+10
>>> print(df_obj)
   A          B     C       D  E     F   G     H
0  1 2017-12-12  10.0  python  3  Lyh 呵呵  20.0
1  1 2017-12-12  11.0    java  3  Lyh 呵呵  21.0
2  1 2017-12-12  12.0     c++  3  Lyh 呵呵  22.0
3  1 2017-12-12  13.0       c  3  Lyh 呵呵  23.0

2-5. 删除列
del df_obj[col_idx]

#通过del方法,删除指定一列的数据
>>> del(df_obj['G'] )
>>> print(df_obj.head())
   A          B     C       D  E     F     H
0  1 2017-12-12  10.0  python  3  Qiku  20.0
1  1 2017-12-12  11.0    java  3  Qiku  21.0
2  1 2017-12-12  12.0     c++  3  Qiku  22.0
3  1 2017-12-12  13.0       c  3  Qiku  23.0

三、Pandas的索引操作

Series和DataFrame中的索引都是Index对象
索引对象不可变,保证了数据的安全

>>> print(type(ser_obj.index))
<class 'pandas.core.indexes.numeric.Int64Index'>
>>> print(type(df_obj.index))
<class 'pandas.core.indexes.range.RangeIndex'>

常见的Index种类
Index,索引
Int64Index,整数索引
MultiIndex,层级索引
DatetimeIndex,时间戳类型
1-1. index 指定行索引名
不指定索引的话,默认从0开始

>>> ser_obj = pd.Series(range(5), index = ['a', 'b', 'c', 'd', 'e'])
>>> print(ser_obj.head())
a    0
b    1
c    2
d    3
e    4
dtype: int64

1-2. 行索引
ser_obj[‘label’], ser_obj[pos]

# 行索引
>>> print(ser_obj['b'])
1
>>> print(ser_obj[2])
2

1-3. 切片索引
ser_obj[2:4], ser_obj[‘label1’: ’label3’]
注意,按索引名切片操作时,是包含终止索引的。

>>> print(ser_obj[1:3])
b    1
c    2
dtype: int64
>>> print(ser_obj['b':'d'])
b    1
c    2
d    3
dtype: int64

1-4. 不连续索引
ser_obj[[‘label1’, ’label2’, ‘label3’]]

>>> print(ser_obj[[0, 2, 4]])
a    0
c    2
e    4
dtype: int64
>>> print(ser_obj[['a', 'e']])
a    0
e    4
dtype: int64

1-5. 布尔索引

>>> ser_bool = ser_obj > 2
>>> print(ser_bool)
a    False
b    False
c    False
d     True
e     True
dtype: bool
>>> print(ser_obj[ser_bool])
d    3
e    4
dtype: int64
>>> print(ser_obj[ser_obj > 2])
d    3
e    4
dtype: int64

2-1. columns 指定列索引名

>>> df_obj = pd.DataFrame(np.random.randn(5,4), columns = ['a', 'b', 'c', 'd'])
>>> print(df_obj.head())
          a         b         c         d
0  1.201658  0.347192  1.371074 -0.111690
1  0.128548 -0.095751  0.415483  0.152507
2  1.927686  0.124433  1.118890  0.031276
3 -1.281139 -0.532217  0.074102 -0.720960
4 -0.290666 -1.252714  0.191163  0.512178

2-2. 列索引
df_obj[['label']]

>>> print(df_obj['a']) # 返回Series类型
0    1.201658
1    0.128548
2    1.927686
3   -1.281139
4   -0.290666
Name: a, dtype: float64

2-3. 不连续索引

>>> print(df_obj)
          a         b         c         d
0  1.201658  0.347192  1.371074 -0.111690
1  0.128548 -0.095751  0.415483  0.152507
2  1.927686  0.124433  1.118890  0.031276
3 -1.281139 -0.532217  0.074102 -0.720960
4 -0.290666 -1.252714  0.191163  0.512178
>>> print(df_obj[['a','c']])
          a         c
0  1.201658  1.371074
1  0.128548  0.415483
2  1.927686  1.118890
3 -1.281139  0.074102
4 -0.290666  0.191163
>>> print(df_obj[[1,3]])
3.高级索引:标签、位置和混合

高级索引有三种:标签,位置,混合
3-1. loc 标签索引
loc是基于标签名的索引,也就是我们自定义的索引名

# Series
>>> print(ser_obj)
a    0
b    1
c    2
d    3
e    4
dtype: int64
>>> print(ser_obj['b':'d'])
b    1
c    2
d    3
dtype: int64
>>> print(ser_obj.loc['b':'d'])
b    1
c    2
d    3
dtype: int64

3-2.DataFrame 不能直接切片,可以通过loc来做切片

# DataFrame
>>> print(df_obj)
          a         b         c         d
0  1.201658  0.347192  1.371074 -0.111690
1  0.128548 -0.095751  0.415483  0.152507
2  1.927686  0.124433  1.118890  0.031276
3 -1.281139 -0.532217  0.074102 -0.720960
4 -0.290666 -1.252714  0.191163  0.512178
>>> print(df_obj['a'])
0    1.201658
1    0.128548
2    1.927686
3   -1.281139
4   -0.290666
Name: a, dtype: float64
# 第一个参数索引行,第二个参数是列
>>> print(df_obj.loc[0:2, 'a'])
0    1.201658
1    0.128548
2    1.927686
Name: a, dtype: float64
>>> print(df_obj.loc[1:3,['b','c']])
          b         c
1 -0.095751  0.415483
2  0.124433  1.118890
3 -0.532217  0.074102

3-2. iloc 位置索引
作用和loc一样,不过是基于索引编号来索引

# Series
>>> print(ser_obj)
a    0
b    1
c    2
d    3
e    4
dtype: int64
>>> print(ser_obj[1:3])
b    1
c    2
dtype: int64
>>> print(ser_obj.iloc[1:3])
b    1
c    2
dtype: int64
# DataFrame
>>> print(df_obj)
          a         b         c         d
0  1.201658  0.347192  1.371074 -0.111690
1  0.128548 -0.095751  0.415483  0.152507
2  1.927686  0.124433  1.118890  0.031276
3 -1.281139 -0.532217  0.074102 -0.720960
4 -0.290666 -1.252714  0.191163  0.512178
>>> print(df_obj.iloc[0:2, 0])
0    1.201658
1    0.128548
Name: a, dtype: float64

3-3. ix 标签与位置混合索引
ix是以上二者的综合,既可以使用索引编号,又可以使用自定义索引,要视情况不同来使用
如果索引既有数字又有英文,容易导致定位的混乱,那么这种方式不建议使用的

# Series
>>> print(ser_obj.ix[1:3])
b    1
c    2
dtype: int64
>>> print(ser_obj.ix['b':'c'])
b    1
c    2
dtype: int64
# DataFrame
>>> print(df_obj.loc[0:2, 'a'])
0    1.201658
1    0.128548
2    1.927686
Name: a, dtype: float64
>>> print(df_obj.ix[0:2, 0])
0    1.201658
1    0.128548
2    1.927686
Name: a, dtype: float64

四、Pandas的对齐运算

是数据清洗的重要过程,可以按索引对齐进行运算,如果没对齐的位置则补NaN

Series的对齐运算

1. Series 按行、索引对齐
ser_obj1 + ser_obj2

>>> ser_obj1 = pd.Series(range(10, 20), index = range(10))
>>> ser_obj2 = pd.Series(range(20, 25), index = range(5))
>>> print(ser_obj1)
0    10
1    11
2    12
3    13
4    14
5    15
6    16
7    17
8    18
9    19
dtype: int64
>>> print(ser_obj2)
0    20
1    21
2    22
3    23
4    24
dtype: int64
>>> print(ser_obj1.add(ser_obj2))
0    30.0
1    32.0
2    34.0
3    36.0
4    38.0
5     NaN
6     NaN
7     NaN
8     NaN
9     NaN
dtype: float64
DataFrame的对齐运算

1. DataFrame 按行、索引对齐
DataFrame做对齐运算时,未对齐数据可以通过fill_value来指定数据做对齐运算
add,sub,mul,div,加减乘除

五、Pandas的函数应用

1. 可直接使用NumPy的函数
在numpy里,可以对数组里的每一个元素进行操作的函数称为ufunc 通用函数(universal function)
在Pandas里可以直接使用Numpy的ufunc

>>> df = pd.DataFrame(np.random.randn(5,4) - 1)
>>> print(df)
          0         1         2         3
0 -1.146296 -1.067455 -2.439676 -0.680181
1 -1.835651 -1.495050 -1.646479 -1.546212
2 -0.121636  0.126804 -3.583221 -3.205977
3 -0.361062  0.139010 -0.816511 -0.800901
4 -0.569759 -1.029041 -1.010752 -1.747664
>>> print(np.abs(df))
          0         1         2         3
0  1.146296  1.067455  2.439676  0.680181
1  1.835651  1.495050  1.646479  1.546212
2  0.121636  0.126804  3.583221  3.205977
3  0.361062  0.139010  0.816511  0.800901
4  0.569759  1.029041  1.010752  1.747664

2. 通过apply将函数应用到列或行上
Axis参数可以指定轴向,默认值为0,方向是列,值为1:方向是行

>>> f = lambda x : x.max()
>>> print(df.apply(lambda x : x.max()))
0   -0.121636
1    0.139010
2   -0.816511
3   -0.680181
dtype: float64
>>> print(df.apply(lambda x : x.max(), axis=1))
0   -0.680181
1   -1.495050
2    0.126804
3    0.139010
4   -0.569759
dtype: float64

3. 通过applymap将函数应用到每个数据上,只用于DataFrame

>>> f1 = lambda x : '%.2f' % x
>>> print(df.applymap(f1))
       0      1      2      3
0  -1.15  -1.07  -2.44  -0.68
1  -1.84  -1.50  -1.65  -1.55
2  -0.12   0.13  -3.58  -3.21
3  -0.36   0.14  -0.82  -0.80
4  -0.57  -1.03  -1.01  -1.75
>>> f2 = lambda x: x+x
>>> print(df_obj.applymap(f2))
          a         b         c         d
0  2.403316  0.694383  2.742148 -0.223379
1  0.257097 -0.191501  0.830965  0.305015
2  3.855371  0.248867  2.237779  0.062553
3 -2.562277 -1.064433  0.148205 -1.441920
4 -0.581332 -2.505427  0.382325  1.024356

4.DataFrame对象可以用apply()和applymap()
apply()应用于行,列,可以通过axis来指定
Series对象只能用apply ,效果等于Pyton的map()
ser_obj.map(func)
ser_obj.apply(func)

5.排序

分为按索引排序和按值排序
5-1. 索引排序
sort_index()
排序默认使用升序排序,ascending=False 为降序排序

# Series
>>> ser_obj2 = pd.Series(range(10, 15), index = np.random.randint(5, size=5))
>>> print(ser_obj2)
1    10
1    11
2    12
4    13
4    14
dtype: int64
>>> ser_obj2.sort_index()
1    10
1    11
2    12
4    13
4    14
dtype: int64
>>> print(ser_obj2.sort_index(ascending = False))  #降序排序
4    13
4    14
2    12
1    10
1    11
dtype: int64

5-2.对DataFrame操作时注意轴方向,默认列,axis = 1 为行

# DataFrame
>>> df_obj = pd.DataFrame(np.random.randn(3, 5),
...                    index=np.random.randint(3, size=3),
...                    columns=np.random.randint(5, size=5))
>>> print(df_obj )
          2         3         3         3         1
2  1.257445 -1.205098  0.128585  0.157959 -0.190920
1 -1.885108 -1.150302  0.688331  0.661057 -0.939931
1  1.220114 -0.820277 -0.691313 -0.562682  1.460008
>>> df_obj_isort = df4.sort_index(axis=1, ascending=False)
>>> print(df_obj_isort)
   lval key4 key3
0     4  one  foo
1     5  one  foo
2     6  one  bar
3     7  two  bar

5-3.按值排序
sort_values(by='column name')
根据某个唯一的列名进行排序,如果有其他相同列名则报错
①按值排序 - Series对象 – 范例

#创建随机Series对象
>>> ser_obj = pd.Series(np.random.randint(10,20,size= 10))
>>> print(ser_obj)
0    15
1    14
2    12
3    13
4    19
5    10
6    13
7    18
8    11
9    10
dtype: int32
>>> print(ser_obj.sort_values()) #默认升序
5    10
9    10
8    11
2    12
3    13
6    13
1    14
0    15
7    18
4    19
>>> print(ser_obj.sort_values(ascending = False)) #降序
4    19
7    18
0    15
1    14
6    13
3    13
2    12
8    11
9    10
5    10
dtype: int32

②.按值排序 - DataFrame对象 – 范例

如果根据某一个行名/列名来排序时,要保证没有其他相同的行名/列名,axis 指定排序的轴方向

>>> df4 = pd.DataFrame(np.random.randn(3, 5), index=np.random.randint(3, size=3), columns=np.random.randint(5, size=5))

6.处理缺失数据

df_obj = pd.DataFrame([[1,2,np.nan,np.nan], [np.nan,3,4,np.nan],list(range(4)])
#   如果某一列中有一个数是Nan或者浮点数,其他数都转换为浮点数
print(df_obj)

6-1. 判断是否存在缺失值:isnull()

#判断是否NaN值,如果是返回True,否则False
print(df_data.isnull())

6-2. 丢弃缺失数据:dropna()
根据axis轴方向,丢弃包含NaN的行或列。
范例

有NaN的时候把相应的行/列去除掉,默认去除行,axis = 1时,去除列

print(df_obj.dropna())
print(df_obj.dropna(axis = 1))
6-3. 填充缺失数据:fillna()
将NaN值替换为指定的值
范例

将NaN值替换为0

print(df_obj.fillna(0))

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

推荐阅读更多精彩内容