为什么学习Pandas?

Pandas 让我们更专注于研究而不是编程。我们发现 Pandas 易于学习,易于使用且易于维护。最重要的是,它提高了我们的生产力。“
Roni Israelov,博士
**
numpy能处理数值型的数据 但是这还不够,我们通常会需要处理字符串、时间序列这样子的数据。
我们得到的数据不止是数组形式的,许多时候还是字典形式的,这是也许需要使用Pandas来操作。

ps不懂的看官方文档就好了http://pandas.pydata.org/pandas-docs/stable/

数据类型-Series

Series 一维带标签数组
DataFrame 二维Series容器
创建一个Series数组:

  1. >>> import pandas as pd
  2. >>> pd.Series([12,45,78,6,11,10])
  3. 0 12
  4. 1 45
  5. 2 78
  6. 3 6
  7. 4 11
  8. 5 10
  9. dtype: int64

可以指定索引:index=list(‘’)

  1. >>> pd.Series([12,45,78,6,11,10],index=list('abcdef'))
  2. a 12
  3. b 45
  4. c 78
  5. d 6
  6. e 11
  7. f 10
  8. dtype: int64

直接通过字典传入

  1. >>> dic1 = {'lalala':10,'xixixi':'haha'}
  2. >>> pd.Series(dic1)
  3. lalala 10
  4. xixixi haha
  5. dtype: object

修改数据类型

和numpy一样 通过astype(‘float’…)
Series有一个to_frame()的方法,可以将Series转化为Dataframe

修改数据

pandas中增加或删除key和python字典中一样

索引与切片

Pandas字典是有序的,pandas的索引对比python自带字典多了一个功能:通过行索引

  1. >>> dic1 = {'lalala':10,'xixixi':'haha'}
  2. >>> d1 = pd.Series(dic1)
  3. >>> d1[1]
  4. 'haha'

由于是有序的,那么可以有类似列表切片的操作:

  1. >>> dic1 = {'lalala':10,'xixixi':'haha','a':'1','b':2}
  2. >>> d1 = pd.Series(dic1)
  3. >>> d1[2:]
  4. a 1
  5. b 2
  6. dtype: object

值得一说的是,还可以通过key名切片,现在你可能会怀疑为什么python字典不设计成有序的了呢:

  1. >>> d1['xixixi':'b']
  2. xixixi haha
  3. a 1
  4. b 2
  5. dtype: object

单独的两行:如果没有这个key 会自动填上NaN

  1. >>> d1[['xixixi','b']]
  2. xixixi haha
  3. b 2
  4. dtype: object

条件选取

  1. >>> d = pd.Series([12,45,78,6,11,10],index=list('abcdef'))
  2. >>> d[d>20]
  3. b 45
  4. c 78
  5. dtype: int64

索引和值

对于一个陌生的 series类型,我们如何知道他的索引和具体的值呢?
Pandas提供index和values的属性可以查看索引和值,且返回值都是可以迭代的,故可以使用。

  1. >>> import pandas as pd
  2. >>> dic1 = {'lalala':10,'xixixi':'haha','a':'1','b':2}
  3. >>> d1 = pd.Series(dic1)
  4. >>> d1.index
  5. Index(['lalala', 'xixixi', 'a', 'b'], dtype='object')
  6. >>> d1.values
  7. array([10, 'haha', '1', 2], dtype=object)

通过list做强类型转换对index 或 values进行切片:
list(d1.index)[2:]

三元运算where

http://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.where.html

  1. >>> s = pd.Series(range(5))
  2. >>> s.where(s > 0)#返回满足条件的值,不满足条件的返回nan
  3. 0 NaN
  4. 1 1.0
  5. 2 2.0
  6. 3 3.0
  7. 4 4.0
  8. dtype: float64
  9. >>> s.mask(s > 0)#满足条件的返回nan,不满足条件的返回值
  10. 0 0.0
  11. 1 NaN
  12. 2 NaN
  13. 3 NaN
  14. 4 NaN
  15. dtype: float64
  16. >>> s.where(s > 1, 10)#满足条件的返回值,不满足条件的返回10
  17. 0 10
  18. 1 10
  19. 2 2
  20. 3 3
  21. 4 4
  22. dtype: int64

数据类型-DataFrame

dataframe是二维的数据,是Series的容器
image.png

创建一个DataFrame

  1. >>> pd.DataFrame(np.arange(24).reshape(4,6))
  2. 0 1 2 3 4 5
  3. 0 0 1 2 3 4 5
  4. 1 6 7 8 9 10 11
  5. 2 12 13 14 15 16 17
  6. 3 18 19 20 21 22 23

{‘’,[‘’],’’,[‘’],’’,[‘’]}或[{‘name’:’xiaobai’,’age’:18,},{‘name’:’xiami’,’age’:18,},{‘name’:’ximi’,’age’:18,}]都可以,key不同则value为nan

  1. >>> d1 = {'name':['xiaoming','xiaobai'],'age':[18,19],'tel':['123','000']}
  2. >>> t1 = pd.DataFrame(d1)
  3. >>> t1
  4. name age tel
  5. 0 xiaoming 18 123
  6. 1 xiaobai 19 000
  7. >>> t1.head(2)
  8. name age tel
  9. 0 xiaoming 18 123
  10. 1 xiaobai 19 000
  11. >>> d = [{'name':'xiaobai','age':18,},{'name':'xiami','age':18,},{'name':'ximi','age':18,},{'name':'xiami','age':18,},{'name':'ximi','age':18,},{'name':'xiasmi','age':15,},{'name':'fximi','age':28,}]
  12. >>> pd.DataFrame(d)
  13. age name
  14. 0 18 xiaobai
  15. 1 18 xiami
  16. 2 18 ximi
  17. 3 18 xiami
  18. 4 18 ximi
  19. 5 15 xiasmi
  20. 6 28 fximi

设置索引

  1. >>> pd.DataFrame(np.arange(9).reshape(3,3),index=list('abc'),columns=list('xyz'))
  2. x y z
  3. a 0 1 2
  4. b 3 4 5
  5. c 6 7 8

快速查看

.info() 查看索引内容和数据类型和内存

  1. print(d1.info())
  2. --------------------output-------------------
  3. <class 'pandas.core.frame.DataFrame'>
  4. RangeIndex: 27820 entries, 0 to 27819 # 27820行
  5. Data columns (total 12 columns): # 12列 名称、类型分别是
  6. country 27820 non-null object
  7. year 27820 non-null int64
  8. sex 27820 non-null object
  9. age 27820 non-null object
  10. suicides_no 27820 non-null int64
  11. population 27820 non-null int64
  12. suicides/100k pop 27820 non-null float64
  13. country-year 27820 non-null object
  14. HDI for year 8364 non-null float64
  15. gdp_for_year ($) 27820 non-null object
  16. gdp_per_capita ($) 27820 non-null int64
  17. generation 27820 non-null object
  18. dtypes: float64(2), int64(4), object(6) # 数据类型的统计
  19. memory usage: 2.5+ MB # 占用内存
  20. None

.describe() 只能查询其中数值或浮点类型的数据

  1. >>> t1
  2. name age tel
  3. 0 xiaoming 18 123
  4. 1 xiaobai 19 000
  5. >>> print(t1.describe())
  6. age
  7. count 2.000000 #行
  8. mean 18.500000 #平均值
  9. std 0.707107 #方差
  10. min 18.000000 #最小值
  11. 25% 18.250000 #四等分点数
  12. 50% 18.500000 #中位数
  13. 75% 18.750000 #四分之三点数
  14. max 19.000000 #最大值

排序

sort_values:栗子中根据age从小到大排序,查看降序只需要再设置ascending=False

  1. >>> t1.sort_values(by='age')
  2. name age tel
  3. 0 xiaoming 18 123
  4. 1 xiaobai 19 000

索引与切片

取行或取列 写数组对行操作,写字符串对列进行操作

  1. >>> pd.DataFrame(d)
  2. age name
  3. 0 18 xiaobai
  4. 1 18 xiami
  5. 2 18 ximi
  6. 3 18 xiami
  7. 4 18 ximi
  8. 5 15 xiasmi
  9. 6 28 fximi
  10. >>> datas = pd.DataFrame(d)
  11. >>> datas[1:5]
  12. age name
  13. 1 18 xiami
  14. 2 18 ximi
  15. 3 18 xiami
  16. 4 18 ximi
  17. # 单独取一列
  18. >>> datas[1:5]['age']
  19. 1 18
  20. 2 18
  21. 3 18
  22. 4 18
  23. Name: age, dtype: int64

同时取某些行与同时取某些列

使用经过pandas优化过的选择方式:
df.loc 通过标签索引行数据
df.iloc 通过位置获取行数据
loc栗子
!注意,使用loc切片时 [0,20]最后一个20是会选中的,与python列表不同。

  1. >>> datas
  2. age name
  3. 0 18 aobai
  4. 1 18 qiami
  5. 2 18 aximi
  6. 3 18 xiami
  7. 4 18 ximi
  8. 5 15 xiasmi
  9. 6 28 fximi
  10. >>> datas.loc[3,'name']
  11. 'xiami'
  12. >>> datas.loc[3:5,'age':]
  13. age name
  14. 3 18 xiami
  15. 4 18 ximi
  16. 5 15 xiasmi
  17. #取第一行和第三行
  18. >>> datas.loc[[0,2],:]
  19. age name
  20. 0 18 xiaobai
  21. 2 18 ximi

iloc栗子 (相当于就是将列的索引变为了0到n的数字)

  1. >>> datas.iloc[[0,2],[1]]
  2. name
  3. 0 xiaobai
  4. 2 ximi

使用datas.iloc[[0,2],[1]] = np.nan是不会报错的(自动转化float类型)。

保留需要的行还可以.reindex([‘a’,’b’])

  1. >>> data = pd.DataFrame(np.arange(9).reshape(3,3))
  2. >>> data
  3. 0 1 2
  4. 0 0 1 2
  5. 1 3 4 5
  6. 2 6 7 8
  7. >>> data.reindex([0,1])
  8. 0 1 2
  9. 0 0 1 2
  10. 1 3 4 5

布尔索引

adult_data = datas[data['age'] >= 18 ]

当有多个条件时使用括号与&:或 |
adult_data = datas[(data['age'] >= 18)`` & ``((data['age'] <= 50)) ]

与字符串有关 例如名字长度大于3的成年人
l_a = datas[(data['age'] >= 18)`` & ``((data['name'].str.len() > 50)) ]

字符串方法

image.png
例如作者中有/分开,可以 data[‘author’].str.split(‘/‘)进行切割,返回的则是Series类型,可以在后面再加上.tolist()转化为列表中嵌套列表。

缺失数据的处理

对于NaN的数据,在numpy中我们是如何处理的?
在pandas中我们处理起来非常容易 判断数据是否为NaN:pd.isnull(df),pd.notnull(df)
处理方式1:删除NaN所在的行列.dropna (axis=0, how=’any’, inplace=False),how=’all’时只有一行全部为nan才会删除,如果implace=True则原地替换,列表已经修改,不必再赋值
处理方式2:填充数据,t.fillna(t.mean()),t.fiallna(t.median()),t.fillna(0)
处理为0的数据:t[t==0]=np.nan
当然并不是每次为0的数据都需要处理 计算平均值等情况,nan是不参与计算的,但是0会 。

读取外部数据

pd.read_之后有很多方法,不一一介绍惹~
这里有一个很有意思的方法:pd.read_clipboard()读取剪贴板的内容

  1. import pandas as pd
  2. file_path = '/home/dwh/Downloads/dogNames2.csv'
  3. d1 = pd.read_csv(file_path)
  4. print(d1)
  5. --------------------output-----------------------
  6. Row_Labels Count_AnimalName
  7. 0 1 1
  8. 1 2 2
  9. 2 40804 1
  10. 3 90201 1
  11. 4 90203 1
  12. 5 102201 1
  13. 6 3010271 1
  14. 7 MARCH 2
  15. 8 APRIL 51
  16. 9 AUGUST 14