为什么学习Pandas?
“ Pandas 让我们更专注于研究而不是编程。我们发现 Pandas 易于学习,易于使用且易于维护。最重要的是,它提高了我们的生产力。“
—Roni Israelov,博士
**
numpy能处理数值型的数据 但是这还不够,我们通常会需要处理字符串、时间序列这样子的数据。
我们得到的数据不止是数组形式的,许多时候还是字典形式的,这是也许需要使用Pandas来操作。
ps不懂的看官方文档就好了http://pandas.pydata.org/pandas-docs/stable/
数据类型-Series
Series 一维带标签数组
DataFrame 二维Series容器
创建一个Series数组:
>>> import pandas as pd
>>> pd.Series([12,45,78,6,11,10])
0 12
1 45
2 78
3 6
4 11
5 10
dtype: int64
可以指定索引:index=list(‘’)
>>> pd.Series([12,45,78,6,11,10],index=list('abcdef'))
a 12
b 45
c 78
d 6
e 11
f 10
dtype: int64
直接通过字典传入
>>> dic1 = {'lalala':10,'xixixi':'haha'}
>>> pd.Series(dic1)
lalala 10
xixixi haha
dtype: object
修改数据类型
和numpy一样 通过astype(‘float’…)
Series有一个to_frame()的方法,可以将Series转化为Dataframe
修改数据
pandas中增加或删除key和python字典中一样
索引与切片
Pandas字典是有序的,pandas的索引对比python自带字典多了一个功能:通过行索引
>>> dic1 = {'lalala':10,'xixixi':'haha'}
>>> d1 = pd.Series(dic1)
>>> d1[1]
'haha'
由于是有序的,那么可以有类似列表切片的操作:
>>> dic1 = {'lalala':10,'xixixi':'haha','a':'1','b':2}
>>> d1 = pd.Series(dic1)
>>> d1[2:]
a 1
b 2
dtype: object
值得一说的是,还可以通过key名切片,现在你可能会怀疑为什么python字典不设计成有序的了呢:
>>> d1['xixixi':'b']
xixixi haha
a 1
b 2
dtype: object
单独的两行:如果没有这个key 会自动填上NaN
>>> d1[['xixixi','b']]
xixixi haha
b 2
dtype: object
条件选取
>>> d = pd.Series([12,45,78,6,11,10],index=list('abcdef'))
>>> d[d>20]
b 45
c 78
dtype: int64
索引和值
对于一个陌生的 series类型,我们如何知道他的索引和具体的值呢?
Pandas提供index和values的属性可以查看索引和值,且返回值都是可以迭代的,故可以使用。
>>> import pandas as pd
>>> dic1 = {'lalala':10,'xixixi':'haha','a':'1','b':2}
>>> d1 = pd.Series(dic1)
>>> d1.index
Index(['lalala', 'xixixi', 'a', 'b'], dtype='object')
>>> d1.values
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
>>> s = pd.Series(range(5))
>>> s.where(s > 0)#返回满足条件的值,不满足条件的返回nan
0 NaN
1 1.0
2 2.0
3 3.0
4 4.0
dtype: float64
>>> s.mask(s > 0)#满足条件的返回nan,不满足条件的返回值
0 0.0
1 NaN
2 NaN
3 NaN
4 NaN
dtype: float64
>>> s.where(s > 1, 10)#满足条件的返回值,不满足条件的返回10
0 10
1 10
2 2
3 3
4 4
dtype: int64
数据类型-DataFrame
创建一个DataFrame
>>> pd.DataFrame(np.arange(24).reshape(4,6))
0 1 2 3 4 5
0 0 1 2 3 4 5
1 6 7 8 9 10 11
2 12 13 14 15 16 17
3 18 19 20 21 22 23
{‘’,[‘’],’’,[‘’],’’,[‘’]}或[{‘name’:’xiaobai’,’age’:18,},{‘name’:’xiami’,’age’:18,},{‘name’:’ximi’,’age’:18,}]都可以,key不同则value为nan
>>> d1 = {'name':['xiaoming','xiaobai'],'age':[18,19],'tel':['123','000']}
>>> t1 = pd.DataFrame(d1)
>>> t1
name age tel
0 xiaoming 18 123
1 xiaobai 19 000
>>> t1.head(2)
name age tel
0 xiaoming 18 123
1 xiaobai 19 000
>>> 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,}]
>>> pd.DataFrame(d)
age name
0 18 xiaobai
1 18 xiami
2 18 ximi
3 18 xiami
4 18 ximi
5 15 xiasmi
6 28 fximi
设置索引
>>> pd.DataFrame(np.arange(9).reshape(3,3),index=list('abc'),columns=list('xyz'))
x y z
a 0 1 2
b 3 4 5
c 6 7 8
快速查看
.info() 查看索引内容和数据类型和内存
print(d1.info())
--------------------output-------------------
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 27820 entries, 0 to 27819 # 27820行
Data columns (total 12 columns): # 12列 名称、类型分别是
country 27820 non-null object
year 27820 non-null int64
sex 27820 non-null object
age 27820 non-null object
suicides_no 27820 non-null int64
population 27820 non-null int64
suicides/100k pop 27820 non-null float64
country-year 27820 non-null object
HDI for year 8364 non-null float64
gdp_for_year ($) 27820 non-null object
gdp_per_capita ($) 27820 non-null int64
generation 27820 non-null object
dtypes: float64(2), int64(4), object(6) # 数据类型的统计
memory usage: 2.5+ MB # 占用内存
None
.describe() 只能查询其中数值或浮点类型的数据
>>> t1
name age tel
0 xiaoming 18 123
1 xiaobai 19 000
>>> print(t1.describe())
age
count 2.000000 #行
mean 18.500000 #平均值
std 0.707107 #方差
min 18.000000 #最小值
25% 18.250000 #四等分点数
50% 18.500000 #中位数
75% 18.750000 #四分之三点数
max 19.000000 #最大值
排序
sort_values:栗子中根据age从小到大排序,查看降序只需要再设置ascending=False
>>> t1.sort_values(by='age')
name age tel
0 xiaoming 18 123
1 xiaobai 19 000
索引与切片
取行或取列 写数组对行操作,写字符串对列进行操作
>>> pd.DataFrame(d)
age name
0 18 xiaobai
1 18 xiami
2 18 ximi
3 18 xiami
4 18 ximi
5 15 xiasmi
6 28 fximi
>>> datas = pd.DataFrame(d)
>>> datas[1:5]
age name
1 18 xiami
2 18 ximi
3 18 xiami
4 18 ximi
# 单独取一列
>>> datas[1:5]['age']
1 18
2 18
3 18
4 18
Name: age, dtype: int64
同时取某些行与同时取某些列
使用经过pandas优化过的选择方式:
df.loc 通过标签索引行数据
df.iloc 通过位置获取行数据
loc栗子
!注意,使用loc切片时 [0,20]最后一个20是会选中的,与python列表不同。
>>> datas
age name
0 18 aobai
1 18 qiami
2 18 aximi
3 18 xiami
4 18 ximi
5 15 xiasmi
6 28 fximi
>>> datas.loc[3,'name']
'xiami'
>>> datas.loc[3:5,'age':]
age name
3 18 xiami
4 18 ximi
5 15 xiasmi
#取第一行和第三行
>>> datas.loc[[0,2],:]
age name
0 18 xiaobai
2 18 ximi
iloc栗子 (相当于就是将列的索引变为了0到n的数字)
>>> datas.iloc[[0,2],[1]]
name
0 xiaobai
2 ximi
使用datas.iloc[[0,2],[1]] = np.nan是不会报错的(自动转化float类型)。
保留需要的行还可以.reindex([‘a’,’b’])
>>> data = pd.DataFrame(np.arange(9).reshape(3,3))
>>> data
0 1 2
0 0 1 2
1 3 4 5
2 6 7 8
>>> data.reindex([0,1])
0 1 2
0 0 1 2
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)) ]
字符串方法
例如作者中有/分开,可以 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()读取剪贴板的内容
import pandas as pd
file_path = '/home/dwh/Downloads/dogNames2.csv'
d1 = pd.read_csv(file_path)
print(d1)
--------------------output-----------------------
Row_Labels Count_AnimalName
0 1 1
1 2 2
2 40804 1
3 90201 1
4 90203 1
5 102201 1
6 3010271 1
7 MARCH 2
8 APRIL 51
9 AUGUST 14