Pandas系列教程(二)


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


摘要

  • 创建数据,使用to_csv()函数生成.txt格式文件,生成1000条随机名字与出生次数的记录
  • 获取数据,使用read_csv()函数从.txt文件中读取数据集
  • 准备数据(make data clean) 即确保生成的数据集正确无误,主要是检查类型, 如df.info()与df.describe()函数
  • 分析数据,主要是排序df.sort_values(),获取最大值df.max(),还有df.head()等函数
  • 可视化,这里用.plot.bar()绘制条形图,直观地显示我们的数据

HTML版本点击此处

# 导入需要的库
import pandas as pd
from numpy import random
import matplotlib.pyplot as plt
import sys 
import matplotlib 

print('Python version ' + sys.version)
print('Pandas version ' + pd.__version__)
print('Matplotlib version ' + matplotlib.__version__)
Python version 3.6.5 |Anaconda, Inc.| (default, Apr 29 2018, 16:14:56) 
[GCC 7.2.0]
Pandas version 0.23.0
Matplotlib version 2.2.2
"""
创建数据集,数据集的内容依旧是1880年的婴儿名字与出生次数
不同于第一节的是,这里同一个婴儿名字可能出现不止一次,我们可以看做是全国各个
省市分别统计的次数
"""

# 初始姓名列表
names = ['Bob','Jessica','Mary','John','Mel']

# 接下来我们以这五个名字为基础创建1000个婴儿名字的记录(有重复)
# 使用的是seed(),numpy.random.randint(),len(),range()和zip()

# 设置随机种子,保证结果相同
random.seed(500)

# 生成随机姓名列表,low,high参数分别传入上下界,用range()控制姓名数量1000条
random_names = [names[random.randint(low=0,high=len(names))] for i in range(1000)]

# 打印前10条记录
random_names[:10]
['Mary',
 'Jessica',
 'Jessica',
 'Bob',
 'Jessica',
 'Jessica',
 'Jessica',
 'Mary',
 'Mary',
 'Mary']
# 与上面操作相同,生成随机出生次数列表
random_births = [random.randint(low=0,high=1000) for i in range(1000)]

random_births[:10]
[968, 155, 77, 578, 973, 124, 155, 403, 199, 191]
# 用zip和list创建我们的数据集

BabyDataSet = list(zip(random_names,random_births))
BabyDataSet[:10]
[('Mary', 968),
 ('Jessica', 155),
 ('Jessica', 77),
 ('Bob', 578),
 ('Jessica', 973),
 ('Jessica', 124),
 ('Jessica', 155),
 ('Mary', 403),
 ('Mary', 199),
 ('Mary', 191)]
# 创建数据帧(DataFrame)

df = pd.DataFrame(data=BabyDataSet,columns=['Names','Births'])
df[:10]
Names Births
0 Mary 968
1 Jessica 155
2 Jessica 77
3 Bob 578
4 Jessica 973
5 Jessica 124
6 Jessica 155
7 Mary 403
8 Mary 199
9 Mary 191
# 调用df.to_csv()函数将数据写入.txt文件,实际与第一节中的操作类似

df.to_csv('births1880.txt',index=False,header=False)
# 从txt中读取数据

# 定义路径,我是linux系统,在windows下带有反斜杠的绝对路径需要用r' '来修正
Location = 'births1880.txt'
df = pd.read_csv(Location)

# 利用info()函数输出数据帧的详细信息
df.info()

"""
数据集中有999条记录
列名为Mary的列有999个值
列名为968的列有999个值
两列的类型一个是object,一个是int64
占用的空间大小为: 15.7+ KB
"""
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 999 entries, 0 to 998
Data columns (total 2 columns):
Mary    999 non-null object
968     999 non-null int64
dtypes: int64(1), object(1)
memory usage: 15.7+ KB





'\n数据集中有999条记录\n列名为Mary的列有999个值\n列名为968的列有999个值\n两列的类型一个是object,一个是int64\n占用的空间大小为: 15.7+ KB\n'
# 输出数据帧前面的记录(默认为5条)

df.head()
Mary 968
0 Jessica 155
1 Jessica 77
2 Bob 578
3 Jessica 973
4 Jessica 124
# 与第一节中的问题相同,我们发现Mary跑到列名的位置上了
df = pd.read_csv(Location,header=None)

# 输出信息,注意比较变化,记录数变到了1000条
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1000 entries, 0 to 999
Data columns (total 2 columns):
0    1000 non-null object
1    1000 non-null int64
dtypes: int64(1), object(1)
memory usage: 15.7+ KB
# 使用tail()输出末尾若干条记录(缺省为5条)
df.tail()
0 1
995 John 151
996 Jessica 511
997 John 756
998 Jessica 294
999 John 152
# 显式地指定列名
df = pd.read_csv(Location,names=['Names','Births'])

df.head()
Names Births
0 Mary 968
1 Jessica 155
2 Jessica 77
3 Bob 578
4 Jessica 973
# 删除文件
import os
os.remove(Location)
# 准确数据,即进行核验工作

# 去掉重复的names,可以用数据帧的unique()属性
df['Names'].unique()
array(['Mary', 'Jessica', 'Bob', 'John', 'Mel'], dtype=object)
for name in df['Names'].unique():
    print(name)
Mary
Jessica
Bob
John
Mel
# 另一种方法,用数据帧的describe()函数
df['Names'].describe()
count     1000
unique       5
top        Bob
freq       206
Name: Names, dtype: object
# 现在我们每个名字拥有多个值,如何把它们统计到一起呢?用数据帧的groupby()函数

# 按Names关键字分组,相同名字为一组
name = df.groupby('Names')

name
<pandas.core.groupby.groupby.DataFrameGroupBy object at 0x7f3d8b65d8d0>
# 把每一组内的values相加
df = name.sum()

df
Births
Names
Bob 106817
Jessica 97826
John 90705
Mary 99438
Mel 102319
# 分析数据
# 选出出现频率最高的名字

# 方法一:排序,ascedning为False表示降序
Sorted = df.sort_values(['Births'],ascending=False)

# 用head()选出第一行即为所求最大值
Sorted.head(1)
Births
Names
Bob 106817
# 方法二,直接用max()
df['Births'].max()
106817
# 数据的可视化,依旧是用matplotlib

# 创建图
df['Births'].plot.bar()

print("The most popular name")
df.sort_values(by='Births',ascending=False)
The most popular name
Births
Names
Bob 106817
Mel 102319
Mary 99438
Jessica 97826
John 90705

Pandas系列教程(二)

相关文章: