Pandas系列教程

Pandas系列教程(一)


  对于想要入门数据科学的朋友们来说,Python是一个很好的选择,除了因为简单的语法外,Python 生态中提供了很多在数值计算方面非常优秀的库,其中Pandas不可不提,Pandas是很强大是数据集处理工具,往往和numpy, matplotlib 等库搭配使用,我也是刚刚开始学习Pandas, 顺便翻译了一下官方的Pandas教程, 这里使用的是jupyter notebook, 因为博客不支持html直接编辑,所以只能转化为markdown 格式,如果想直接查看html版本可点击每一节下的链接。本文仅供学习和交流使用,欢迎大家交流和指正!


摘要

  • 数据帧(DataFrame)与结构
  • 创建数据,使用to_csv()函数创建数据集
  • 获取数据,使用read_csv()函数读取数据集
  • 准备数据(make data clean) 即确保生成的数据集正确无误,主要是检查类型
  • 分析数据,主要是排序df.sort_values(),获取最大值df.max(),还有df.head()等函数
  • 可视化,使用matplotlib,直观地显示我们的数据

HTML版本点击此处

#导入需要的库文件

from pandas import DataFrame, read_csv

import matplotlib.pyplot as plt
import pandas as pd
import sys
import matplotlib

%matplotlib inline

print('Python version' + sys.version)
print('Pandas version' + pd.__version__)
print('Matplotlib version' + matplotlib.__version__)
Python version3.6.5 |Anaconda, Inc.| (default, Apr 29 2018, 16:14:56) 
[GCC 7.2.0]
Pandas version0.23.0
Matplotlib version2.2.2
# 创建初始数据集,这里我们统计婴儿名字与相应的出生次数
names = ['Bob','Jessica','Mary','John','Mel']
births = [968,155,77,578,973]

# 用zip+list命令生成我们的数据集,元组列表的形式
BabyDataSet = list(zip(names,births))
BabyDataSet
[('Bob', 968), ('Jessica', 155), ('Mary', 77), ('John', 578), ('Mel', 973)]
# 完成数据集的创建后,我们用pandas库把生成的数据集保存到csv格式的文件中
# df 是一个数据帧(DataFrame)的形式,类似于数据库中的表

# 将数据集传入data参数,columns参数传入的是我们的关键字(类似于key)
df = pd.DataFrame(data=BabyDataSet,columns=['Names','Births'])
df
Names Births
0 Bob 968
1 Jessica 155
2 Mary 77
3 John 578
4 Mel 973
"""
然后用 DataFrame 对象的to_csv()函数生成.csv文件
其中index 参数设置为False表示生成的csv文件中将不带行标(index)
header=False 表示不生成 Names Births 两个关键字
"""

df.to_csv('births1880.csv',index=False,header=False)

"""
我们得到的csv文件内容如下:
Bob, 968
Jessica, 155
Mary, 77
John, 578
Mel, 973
"""
"""
从csv文件中读取数据,调用 read_csv() 库函数

先定义路径
我的csv就生成在当前目录下,如果需要在windows平台下用绝对路径读取可以参考
Location = r'C:\Users\dreamboy\births1880.csv'
其中的r 是用来修正 反斜杠的
"""

Location = 'births1880.csv'
df = pd.read_csv(Location)

df
Bob 968
0 Jessica 155
1 Mary 77
2 John 578
3 Mel 973
"""
可以看到我们的结果好像出了点问题! Bob 968跑到了列名的位置上
解决这个问题我们需要用read_csv()函数中的header参数
将header设置为None 表示告诉函数我们要读取的csv文件中是没有header(列关键字)的,
它就不会把Bob误认为是header了!
"""

df = pd.read_csv(Location,header=None)
df
0 1
0 Bob 968
1 Jessica 155
2 Mary 77
3 John 578
4 Mel 973
"""
此时header 变为了0和1,这是默认值,为了达到我们想要的效果,需要显式地指定
names参数,就和我们创建数据帧时一样
"""

df = pd.read_csv(Location,names=['Names','Births'])
df
Names Births
0 Bob 968
1 Jessica 155
2 Mary 77
3 John 578
4 Mel 973
# 删除csv文件

import os
os.remove(Location)
# 准备数据,检查数据帧的类型以及数据帧内各个关键字的类型

# 将输出所有列的类型
df.dtypes
Names     object
Births     int64
dtype: object
# 检查Births的类型是否正确,需要为整数
df.Births.dtype
dtype('int64')
"""
当我们完成了上述步骤并确认数据类型无误后我们就可以开始分析数据了

- 对数据帧df进行排序并选出最上面一行
- 用max() 属性来找到出生次数的最大值

"""

# 方法一
# Births参数表示以Births为参考列进行排序,ascending设置为False表示降序,否则升序
Sorted = df.sort_values(['Births'],ascending=False)

# 用df.head() 得到前面若干行,这里选第一行
Sorted.head(1)
Names Births
4 Mel 973
# 方法二
# 直接对df['Births']调用max()方法

df['Births'].max()
973
# 数据的可视化,用的是matplotlib的plt
# 把Births 列进行绘图我们可以很直观地得到最流行的名字

# 生成图,实际上是生成了一个plt中的figure
df['Births'].plot()

# 获取数据集中的最大值,结果是973
MaxValue = df['Births'].max()

# 得到具有最高出生次数的名字,这里的结果只有一个Mel,在最大值不唯一的情况下返回列表
MaxName = df['Names'][df['Births'] == MaxValue].values

# 传入标注的文字
Text = str(MaxValue) + ' - ' + MaxName

# 加入注释
plt.annotate(Text,xy=(1,MaxValue),xytext=(8,0),
            xycoords=('axes fraction','data'),textcoords='offset points')

print("The most popular name")
df[df['Births'] == df['Births'].max()]

The most popular name
Names Births
4 Mel 973

Pandas系列教程

# 官方文档第一节的内容到此结束了,那么此外我们还可以多做一些小试验

# 每一列都是列表的形式,通过index可以访问
df['Births'][1]
155
df1 = df.copy()

# 这里修改对应位置的值为出现警告,意思大致是担心我们原来的数据丢失,所以保险的方法是
#  先copy 一下
df1['Births'][1] = 973
/home/dreamboy/anaconda3/lib/python3.6/site-packages/ipykernel_launcher.py:3: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  This is separate from the ipykernel package so we can avoid doing imports until
df
Names Births
0 Bob 968
1 Jessica 155
2 Mary 77
3 John 578
4 Mel 973
df1
Names Births
0 Bob 968
1 Jessica 973
2 Mary 77
3 John 578
4 Mel 973
#可以看到在最高出生次数名字不唯一的时候返回的是一个列表
array = df1['Names'][df1['Births'] == df1['Births'].max()].values

array
array(['Jessica', 'Mel'], dtype=object)
array[0]
'Jessica'
#导入需要的库文件

from pandas import DataFrame, read_csv

import matplotlib.pyplot as plt
import pandas as pd
import sys
import matplotlib

%matplotlib inline

print('Python version' + sys.version)
print('Pandas version' + pd.__version__)
print('Matplotlib version' + matplotlib.__version__)
Python version3.6.5 |Anaconda, Inc.| (default, Apr 29 2018, 16:14:56) 
[GCC 7.2.0]
Pandas version0.23.0
Matplotlib version2.2.2
# 创建初始数据集,这里我们统计婴儿名字与相应的出生次数
names = ['Bob','Jessica','Mary','John','Mel']
births = [968,155,77,578,973]

# 用zip+list命令生成我们的数据集,元组列表的形式
BabyDataSet = list(zip(names,births))
BabyDataSet
[('Bob', 968), ('Jessica', 155), ('Mary', 77), ('John', 578), ('Mel', 973)]
# 完成数据集的创建后,我们用pandas库把生成的数据集保存到csv格式的文件中
# df 是一个数据帧(DataFrame)的形式,类似于数据库中的表

# 将数据集传入data参数,columns参数传入的是我们的关键字(类似于key)
df = pd.DataFrame(data=BabyDataSet,columns=['Names','Births'])
df
Names Births
0 Bob 968
1 Jessica 155
2 Mary 77
3 John 578
4 Mel 973
"""
然后用 DataFrame 对象的to_csv()函数生成.csv文件
其中index 参数设置为False表示生成的csv文件中将不带行标(index)
header=False 表示不生成 Names Births 两个关键字
"""

df.to_csv('births1880.csv',index=False,header=False)

"""
我们得到的csv文件内容如下:
Bob, 968
Jessica, 155
Mary, 77
John, 578
Mel, 973
"""
"""
从csv文件中读取数据,调用 read_csv() 库函数

先定义路径
我的csv就生成在当前目录下,如果需要在windows平台下用绝对路径读取可以参考
Location = r'C:\Users\dreamboy\births1880.csv'
其中的r 是用来修正 反斜杠的
"""

Location = 'births1880.csv'
df = pd.read_csv(Location)

df
Bob 968
0 Jessica 155
1 Mary 77
2 John 578
3 Mel 973
"""
可以看到我们的结果好像出了点问题! Bob 968跑到了列名的位置上
解决这个问题我们需要用read_csv()函数中的header参数
将header设置为None 表示告诉函数我们要读取的csv文件中是没有header(列关键字)的,
它就不会把Bob误认为是header了!
"""

df = pd.read_csv(Location,header=None)
df
0 1
0 Bob 968
1 Jessica 155
2 Mary 77
3 John 578
4 Mel 973
"""
此时header 变为了0和1,这是默认值,为了达到我们想要的效果,需要显式地指定
names参数,就和我们创建数据帧时一样
"""

df = pd.read_csv(Location,names=['Names','Births'])
df
Names Births
0 Bob 968
1 Jessica 155
2 Mary 77
3 John 578
4 Mel 973
# 删除csv文件

import os
os.remove(Location)
# 准备数据,检查数据帧的类型以及数据帧内各个关键字的类型

# 将输出所有列的类型
df.dtypes
Names     object
Births     int64
dtype: object
# 检查Births的类型是否正确,需要为整数
df.Births.dtype
dtype('int64')
"""
当我们完成了上述步骤并确认数据类型无误后我们就可以开始分析数据了

- 对数据帧df进行排序并选出最上面一行
- 用max() 属性来找到出生次数的最大值

"""

# 方法一
# Births参数表示以Births为参考列进行排序,ascending设置为False表示降序,否则升序
Sorted = df.sort_values(['Births'],ascending=False)

# 用df.head() 得到前面若干行,这里选第一行
Sorted.head(1)
Names Births
4 Mel 973
# 方法二
# 直接对df['Births']调用max()方法

df['Births'].max()
973
# 数据的可视化,用的是matplotlib的plt
# 把Births 列进行绘图我们可以很直观地得到最流行的名字

# 生成图,实际上是生成了一个plt中的figure
df['Births'].plot()

# 获取数据集中的最大值,结果是973
MaxValue = df['Births'].max()

# 得到具有最高出生次数的名字,这里的结果只有一个Mel,在最大值不唯一的情况下返回列表
MaxName = df['Names'][df['Births'] == MaxValue].values

# 传入标注的文字
Text = str(MaxValue) + ' - ' + MaxName

# 加入注释
plt.annotate(Text,xy=(1,MaxValue),xytext=(8,0),
            xycoords=('axes fraction','data'),textcoords='offset points')

print("The most popular name")
df[df['Births'] == df['Births'].max()]

The most popular name
Names Births
4 Mel 973

Pandas系列教程

# 官方文档第一节的内容到此结束了,那么此外我们还可以多做一些小试验

# 每一列都是列表的形式,通过index可以访问
df['Births'][1]
155
df1 = df.copy()

# 这里修改对应位置的值为出现警告,意思大致是担心我们原来的数据丢失,所以保险的方法是
#  先copy 一下
df1['Births'][1] = 973
/home/dreamboy/anaconda3/lib/python3.6/site-packages/ipykernel_launcher.py:3: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  This is separate from the ipykernel package so we can avoid doing imports until
df
Names Births
0 Bob 968
1 Jessica 155
2 Mary 77
3 John 578
4 Mel 973
df1
Names Births
0 Bob 968
1 Jessica 973
2 Mary 77
3 John 578
4 Mel 973
#可以看到在最高出生次数名字不唯一的时候返回的是一个列表
array = df1['Names'][df1['Births'] == df1['Births'].max()].values

array
array(['Jessica', 'Mel'], dtype=object)
array[0]
'Jessica'