Pandas操作
- pandas DataFrame
- pandas Series
pandas DataFrame
我们存储数据最常用的形式是表格
- 表格就是由行和列所构成一种有序的组织形式
- 表格的第一行一般是变量名,也称为表头header
- 不同的变量可以是不同的数据类型
numpy array只能存储一种数据类型,一个表格通常不仅仅只有数字类型。我们需要使用pandas包来处理
- pandas是数据科学中最常用的包之一,可以高效的处理各种数据
- pandas是基于numpy构建的
- pandas中重要的数据结构是series和DataFrame
# 导入pandas包
import pandas as pd
观察数据常用方法
- df.head() 查看数据框df数据前几行
- df.tail() 查看数据库df数据后几行
- df.info() 查看数据框df总体信息
- df.describe() 查看数据框df的各项统计信息
- df.index 查看数据框df的行索引
- df.columns 查看数据框的列名
- df.shape 查看数据框的形状,行和列
Series数据的一些统计分析函数
- se.unique() 获取series数据中的数值种类
- se.value_counts() 统计series数据中的数据种类以及对应数据的个数
- se.mean() 计算series数据的均值
- se.std() 计算series数据的标准差
- se.median()计算series数据的中位数
- se.max() 计算series数据的最大值
- se.min() 计算series数据的最小值
- se.count() 计算series数据的个数
pandas 绘图函数
- df.plot(kind='scatter',x=,y=) 散点图
- df.plot(kind = 'box') 箱图
- df.boxplot(by='column_name') 箱图,并按 column_name 分组
从字典创建一个DataFrame
gdp = {"country":["United States", "China", "Japan", "Germany", "United Kingdom"],
"capital":["Washington, D.C.", "Beijing", "Tokyo", "Berlin", "London"],
"population":[323, 1389, 127, 83, 66],
"gdp":[19.42, 11.8, 4.84, 3.42, 2.5],
"continent":["North America", "Asia", "Asia", "Europe", "Europe"]}
# 使用字典创建DataFrame,key将作为表头
gdp_df = pd.DataFrame(gdp)
gdp_df#列索引是第一行 行索引是0-4
# 我们可以使用index选项来添加自定义的行标签
# 使用column选项可以选择列的顺序
gdp_df = pd.DataFrame(gdp,columns=['country','capital','population','gdp','continent'],index = ['us','cn','jp','de','uk'])
gdp_df
gdp_df = pd.DataFrame(gdp,columns=gdp.keys(),index = ['us','cn','jp','de','uk'])
gdp_df
修改行和列的标签
可以直接使用index和columns直接修改
gdp_df.index = ["US", "CN", "JP", "DE", "UK"]
gdp_df.columns = ["Country", "Capital", "Population", "GDP", "Continent"]
gdp_df
增加一列数据
# 增加rank列,表示他们的GDP处在前5位
gdp_df['rank'] = 'TOP5 GDP'
# 增加国土面积变量,以百万公里计(数据来源:http://data.worldbank.org/)
gdp_df['Area'] = [9.15, 9.38, 0.37, 0.35, 0.24]
gdp_df
pandas series
- pandas中的series对象是另一个重要的数据结构
- 可以将其视为一个一维的DataFrame或者一个一维数组array加上一个索引index
- series的作用之一就是数据过滤和分组
# 一个最简单series
series = pd.Series([2,4,5,7,3],index=['a','b','c','d','e'])
series
a 2
b 4
c 5
d 7
e 3
dtype: int64
# 当我们使用点操作符来查看一个变量时,返回的是一个series
gdp_df.GDP#US...UK是索引
US 19.42
CN 11.80
JP 4.84
DE 3.42
UK 2.50
Name: GDP, dtype: float64
# 可以直接查看索引
gdp_df.GDP.index
Index(['US', 'CN', 'JP', 'DE', 'UK'], dtype='object')
gdp_df.GDP > 4 #返回一个bool型的series 索引不参与运算
US True
CN True
JP True
DE False
UK False
Name: GDP, dtype: bool
我们也可以将series视为一个长度固定且有顺序的字典,一些用于字典的函数也可以用于series
gdp_dict = {"US": 19.42, "CN": 11.80, "JP": 4.84, "DE": 3.42, "UK": 2.5}
gdp_series = pd.Series(gdp_dict)
gdp_series
CN 11.80
DE 3.42
JP 4.84
UK 2.50
US 19.42
dtype: float64
# 判断us标签是否在序列中
'US' in gdp_series
True
数据的选择
- 可以使用[]来选择所需要的列,里面那个括号可以传入列索引或者列索引组成的列表 如果是列表则产生DataFrame 如果只是列索引则产生series
- 也可以使用点语法获取某一列
- 使用[]切片 来选择需要的行
- 使用loc和iloc方法选择行和列
- 使用bool索引筛选数据
# 通过列索引选择一列
gdp_df['Country']
US United States
CN China
JP Japan
DE Germany
UK United Kingdom
Name: Country, dtype: object
- 选择列
# 同时选取多列
gdp_df[['Country','GDP']]
# 使用点语法获取某一列 得到的也是series
gdp_df.GDP
US 19.42
CN 11.80
JP 4.84
DE 3.42
UK 2.50
Name: GDP, dtype: float64
- 选择行
# 行选择和2d数组选择类似
gdp_df[2:5]
# loc方法是基于行标签和列标签的选取数据的方法
# 可以选取特定的行或列 也可以同时指定需要的行和列
# 和二维的numpy array的格式非常类似
# 第一个参数是行标签,第二个参数是列标签
gdp_df.loc[['JP','DE']]
# 以上例子选取了所有的列,我们可以筛选所需要的列
gdp_df.loc[['JP','DE'],['Country','GDP','Continent']]
# 选取所有的行,我们可以使用:表示选取所有的行
gdp_df.loc[:,['Country','GDP','Continent']]
# iloc方法 和 loc方法类似,但是是使用行列索引进行的数据筛选而不是用标签
gdp_df.iloc[[2,3]] #等价于gdp_df.loc[['JP','DE']]
gdp_df.loc[["JP","DE"],["Country", "GDP", "Continent"]]
gdp_df.iloc[[2,3],[0,3,4]]
# 等价于gdp_df.loc[:, ["country", "GDP", "continent"]]
gdp_df.iloc[:, [0,3,4]]
使用布尔索引筛选数据
- 可以使用pandas series 来获取一个 Boolean series
- 布尔索引的使用和numpy的array类似
- 可以结合[]或loc一起使用
# 使用bool索引筛选数据
# 选出亚洲国家 和下面的命令产生的结果是一样的
gdp_df[gdp_df.Continent == 'Asia']
gdp_df.loc[gdp_df.Continent == 'Asia']
# 选出gdp大于3兆亿美元的欧洲国家
gdp_df[(gdp_df.GDP>3) & (gdp_df.Continent == 'Europe')]
# 选出亚洲或者北美洲的国家记录
gdp_df[(gdp_df.Continent=='Asia') | (gdp_df.Continent == 'North America')]
# 或者使用isin
gdp_df[gdp_df.Continent.isin(['Asia','North America'])]
数据的导入和观察
# 用列表来存储列标签
col_names = ['sepal_length', 'sepal_width', 'petal_length', 'petal_width', 'species']
# 读取数据,并指定列标签
iris = pd.read_csv('iris.txt',names=col_names)
# 读取到的iris是DataFrame数据类型
# 使用head和tail查看头尾
print(iris.head(10))
print(iris.tail(10))
sepal_length sepal_width petal_length petal_width species
0 5.1 3.5 1.4 0.2 Iris-setosa
1 4.9 3.0 1.4 0.2 Iris-setosa
2 4.7 3.2 1.3 0.2 Iris-setosa
3 4.6 3.1 1.5 0.2 Iris-setosa
4 5.0 3.6 1.4 0.2 Iris-setosa
5 5.4 3.9 1.7 0.4 Iris-setosa
6 4.6 3.4 1.4 0.3 Iris-setosa
7 5.0 3.4 1.5 0.2 Iris-setosa
8 4.4 2.9 1.4 0.2 Iris-setosa
9 4.9 3.1 1.5 0.1 Iris-setosa
sepal_length sepal_width petal_length petal_width species
140 6.7 3.1 5.6 2.4 Iris-virginica
141 6.9 3.1 5.1 2.3 Iris-virginica
142 5.8 2.7 5.1 1.9 Iris-virginica
143 6.8 3.2 5.9 2.3 Iris-virginica
144 6.7 3.3 5.7 2.5 Iris-virginica
145 6.7 3.0 5.2 2.3 Iris-virginica
146 6.3 2.5 5.0 1.9 Iris-virginica
147 6.5 3.0 5.2 2.0 Iris-virginica
148 6.2 3.4 5.4 2.3 Iris-virginica
149 5.9 3.0 5.1 1.8 Iris-virginica
# 使用info方法查看数据的总体信息
iris.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 150 entries, 0 to 149
Data columns (total 5 columns):
sepal_length 150 non-null float64
sepal_width 150 non-null float64
petal_length 150 non-null float64
petal_width 150 non-null float64
species 150 non-null object
dtypes: float64(4), object(1)
memory usage: 5.9+ KB
# 使用shape可以查看DataFrame的行数和列数
iris.shape
(150, 5)
# 这是的species是分类变量,可以使用unique方法来查看品种的名字
iris.species.unique()
array(['Iris-setosa', 'Iris-versicolor', 'Iris-virginica'], dtype=object)
# 统计不同品种的数量
iris.species.value_counts()
Iris-setosa 50
Iris-versicolor 50
Iris-virginica 50
Name: species, dtype: int64
关于变量的种类
- 第一类是数量型(quantitative)变量,其中又可以进一步分为两种
- 连续型的(continuous),比如一个人的身高和体重,当天的温度等等。
- 离散型的(discrete),比如一个医院医生的人数,每天航班的次数等等。
- 第二类变量是性质型(qualitative)变量,也称为分类变量(categorical)其中也可以进一步分为两类
- 无序型变量,比如人的性别,上面列子中鸢尾花的品种。
- 有序型(ordinal),比如人的教育(本科,硕士,博士),收入分组(低,中,高收入)。
# 数据选择复习
# 选取花瓣数据,即 petal_length 和 petal_width 这两列
# 方法1 使用[[]]
petal = iris[['petal_length','petal_width']]
petal.head()
# 方法2 使用loc
petal = iris.loc[:,['petal_length','petal_width']]
petal.head()
# 方法3 使用iloc
petal = iris.iloc[:,2:4]
petal.head()
# 选取行索引为5-10的数据行
# 方法1 []切片
iris[5:11]
# 方法2 iloc
iris.iloc[5:11,:]
# 选取品种为 Iris-versicolor 的数据
versicolor = iris[iris.species == 'Iris-versicolor']
versicolor.head()
数据可视化初探
# 设置在notebook中直接展示图形输出
# 注意DataFrame也是基于matplotlib作图的
%matplotlib inline
# 设置图片清晰度
%config InlineBackend.figure_format = 'retina'
散点图
# 我们首先画散点图(sactter plot),x轴上画出花瓣的长度,y轴上画出花瓣的宽度
iris.plot(kind='scatter',x='petal_length',y='petal_width')
<matplotlib.axes._subplots.AxesSubplot at 0x10ef71048>
# ?iris.plot 查看使用帮助
# 使用bool索引获取三个品种的数据
setosa = iris[iris.species == 'Iris-setosa']
versicolor = iris[iris.species == 'Iris-versicolor']
virginica = iris[iris.species == 'Iris-virginica']
# 画图
ax = setosa.plot(kind='scatter', x="petal_length", y="petal_width", color='red',figsize=(10,6),label='setosa')
versicolor.plot(kind='scatter', x="petal_length", y="petal_width", color='Green', ax=ax, label='versicolor')
virginica.plot(kind='scatter', x="petal_length", y="petal_width", color='Orange', ax=ax, label='virginica')
<matplotlib.axes._subplots.AxesSubplot at 0x10e98fda0>
箱图
# 使用mean方法获取花瓣宽度均值
iris.petal_width.mean()
1.1986666666666672
# 使用median方法获取花瓣宽度中位数
iris.petal_width.median()
1.3
# 使用describe方法来总结变量值
iris.describe()
iris.petal_width.describe()
count 150.000000
mean 1.198667
std 0.763161
min 0.100000
25% 0.300000
50% 1.300000
75% 1.800000
max 2.500000
Name: petal_width, dtype: float64
# 绘制花瓣宽度的箱图
# 箱图展示了数据中的中位数,四分位数,最大值,最小值
iris.petal_width.plot(kind='box')
<matplotlib.axes._subplots.AxesSubplot at 0x10f23eac8>
# 按品种分类,分别绘制不同品种花瓣宽度的箱图
iris[['petal_width','species']].boxplot(by='species',grid=False,figsize=(10,6))
<matplotlib.axes._subplots.AxesSubplot at 0x11374bda0>