首页 > 编程语言 >Python-数据分析学习手册-全-

Python-数据分析学习手册-全-

时间:2024-10-01 21:02:36浏览次数:13  
标签:数据分析 Python 手册 df pd Listing 清单 import 数据

Python 数据分析学习手册(全)

原文:Learn Data Analysis with Python

协议:CC BY-NC-SA 4.0

一、如何使用这本书

如果您已经在使用 Python 进行数据分析,只需浏览这本书的目录。你可能会发现很多你希望知道如何用 Python 做的事情。如果是这样,请随意直接翻到那一章并开始工作。每一课都尽可能地自成一体。

被警告!这本书与其说是教科书,不如说是练习册。

如果您没有使用 Python 进行数据分析,请从头开始。如果您已经完成了整个工作簿,那么当您完成时,您应该对如何使用 Python 进行数据分析有更好的了解。

如果您对数据分析一无所知,本工作簿可能不是开始的地方。然而,试一试,看看它如何为你工作。

安装 Jupyter 笔记本电脑

安装和使用 Python 的最快方法是做你已经知道如何做的事情,并且你知道如何使用你的浏览器。为什么不用 Jupyter 笔记本?

Jupyter 笔记本是什么?

Jupyter Notebook 是一个在浏览器中运行的交互式 Python shell。当通过 Anaconda 安装时,很容易快速设置 Python 开发环境。既然设置简单,运行方便,那学 Python 也就容易了。

Jupyter Notebook 把你的浏览器变成一个 Python 开发环境。你唯一需要安装的是 Anaconda。本质上,它允许您输入几行 Python 代码,按 CTRL+Enter,然后执行代码。您在单元格中输入代码,然后运行当前选定的单元格。还可以选择运行笔记本中的所有单元格。如果您正在开发一个更大的程序,这是很有用的。

什么是蟒蛇?

Anaconda 是确保您不会花一整天时间安装 Jupyter 的最简单的方法。只需下载 Anaconda 包并运行安装程序。Anaconda 软件包包含创建 Python 开发环境所需的一切。Anaconda 有两个版本——一个用于 Python 2.7,一个用于 Python 3.x。出于本指南的目的,请安装 Python 2.7 的版本。

Anaconda 是一个开源数据科学平台。它包含 100 多个用于 Python、R 和 Scala 的包。您可以毫不费力地快速下载并安装 Anaconda。安装后,您可以更新包或 Python 版本,或者为不同的项目创建环境。

入门指南

  1. https://www.anaconda.com/download 下载安装 Anaconda。
  2. 一旦您安装了 Anaconda,您就可以创建您的第一个笔记本了。运行作为 Anaconda 的一部分安装的 Jupyter 笔记本应用程序。
  3. 您的浏览器将打开到以下地址:http://localhost:8888。如果您正在运行 Internet Explorer,请关闭它。使用 Firefox 或 Chrome 获得最佳效果。从那里,浏览到http://localhost:8888
  4. 开始新的笔记本。在浏览器的右侧,单击显示“新建”的下拉按钮,然后选择 Python 或 Python 2。
  5. 这将在另一个浏览器选项卡中打开一个新的 iPython 笔记本。您可以在多个标签中打开多个笔记本。
  6. Jupyter 笔记本包含细胞。您可以在每个单元格中键入 Python 代码。要开始(对于 Python 2.7),在第一个单元格中键入print "Hello, World!",然后按 CTRL+Enter。如果您使用的是 Python 3.5,那么这个命令就是print("Hello, World!")

获取工作簿练习的数据集

  1. http://www.ajhenley.com/dwnld 下载数据集文件。
  2. 将文件datasets.zip上传到与笔记本相同的文件夹中的 Anaconda。
  3. 运行清单 1-1 中的 Python 代码来解压数据集。
path_to_zip_file = "datasets.zip"
directory_to_extract_to = ""

import zipfile
zip_ref = zipfile.ZipFile(path_to_zip_file, 'r')
zip_ref.extractall(directory_to_extract_to)
zip_ref.close()

Listing 1-1Unzipping dataset.zip

二、将数据导入和导出 Python

数据分析的第一阶段是获取数据。如果您不知道自己在做什么,那么将数据从存储位置移动到分析工具中,然后再移出可能是一项艰巨的任务。Python 和它的库试图让它尽可能简单。

只需几行代码,您就能够以下列格式导入和导出数据:

  • 战斗支援车
  • 超过
  • 结构化查询语言

从 CSV 文件加载数据

通常,数据会以文件或数据库链接的形式到达我们这里。参见清单 2-1 了解如何从 CSV 文件加载数据。

import pandas as pd
Location = "datasets/smallgradesh.csv"
df = pd.read_csv(Location, header=None)
Listing 2-1Loading Data from CSV File

现在,让我们看看我们的数据是什么样子的(清单 2-2 ):

df.head()
Listing 2-2Display First Five Lines of Data

如您所见,我们的 dataframe 缺少列标题。或者,更确切地说,有头文件,但它们没有作为头文件加载;它们是作为数据的第一行加载的。要加载包含标题的数据,可以使用清单 2-3 中所示的代码。

import pandas as pd
Location = "datasets/gradedata.csv"
df = pd.read_csv(Location)
Listing 2-3Loading Data from CSV File with Headers

然后,像以前一样,我们通过运行清单 2-4 中所示的代码来看看数据是什么样子的。

df.head()
Listing 2-4Display First Five Lines of Data

如果您有一个不包含标题的数据集,您可以在以后添加它们。要添加它们,我们可以使用清单 2-5 中显示的选项之一。

import pandas as pd
Location = "datasets/smallgrades.csv"
# To add headers as we load the data...
df = pd.read_csv(Location, names=['Names','Grades'])
# To add headers to a dataframe
df.columns = ['Names','Grades']
Listing 2-5Loading Data from CSV File and Adding Headers

轮到你了

你能从自己上传和导入的文件中制作一个数据帧吗?让我们找出答案。转到以下网站,其中包含美国人口普查数据( http://census.ire.org/data/bulkdata.html ),并下载一个州的 CSV 数据文件。现在,尝试将数据导入 Python。

将数据保存到 CSV

也许你想在分析数据时保存你的进度。也许您只是在使用 Python 来处理一些数据,以便稍后在另一个工具中进行分析。或者您可能有其他原因要将数据帧导出为 CSV 文件。清单 2-6 中显示的代码是如何做到这一点的例子。

import pandas as pd
names = ['Bob','Jessica','Mary','John','Mel']
grades = [76,95,77,78,99]
GradeList = zip(names,grades)
df = pd.DataFrame(data = GradeList, columns=['Names','Grades'])

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

Listing 2-6Exporting a Dataset to CSV

第 1 行到第 6 行是创建数据帧的行。第 7 行是将数据帧df导出到名为studentgrades.csv的 CSV 文件的代码。

我们使用的唯一参数是indexheader。将这些参数设置为 false 将会阻止导出索引和标题名称。更改这些参数的值,以便更好地理解它们的用途。

如果您想深入了解to_csv方法,当然可以使用清单 2-7 中所示的代码。

df.to_csv?
Listing 2-7Getting Help on to_csv

轮到你了

你能把清单 2-8 中的代码创建的数据帧导出到 CSV 吗?

import pandas as pd
names = ['Bob','Jessica','Mary','John','Mel']
grades = [76,95,77,78,99]
bsdegrees = [1,1,0,0,1]
msdegrees = [2,1,0,0,0]
phddegrees = [0,1,0,0,0]
Degrees = zip(names,grades,bsdegrees,msdegrees,phddegrees)
columns = ['Names','Grades','BS','MS','PhD']
df = pd.DataFrame(data = Degrees, columns=column)

df

Listing 2-8Creating a Dataset for the Exercise

从 Excel 文件加载数据

通常,数据会以文件或数据库链接的形式到达我们这里。让我们看看如何从 Excel 文件中加载数据(清单 2-9 )。

import pandas as pd
Location = "datasets/gradedata.xlsx"
df = pd.read_excel(Location)
Listing 2-9Loading Data from Excel File

现在,让我们看看我们的数据是什么样子的(清单 2-10 )。

df.head()
Listing 2-10Display First Five Lines of Data

如果您希望更改或简化列名,您可以运行清单 2-11 中所示的代码。

df.columns = ['first','last','sex','age','exer','hrs','grd','addr']
df.head()
Listing 2-11Changing Column Names

轮到你了

你能从自己上传和导入的文件中制作一个数据帧吗?让我们找出答案。转到 https://www.census.gov/support/USACdataDownloads.html ,下载页面底部的一个 Excel 数据文件。现在,尝试将数据导入 Python。

将数据保存到 Excel 文件

清单 2-12 中显示的代码是如何做到这一点的例子。

import pandas as pd
names = ['Bob','Jessica','Mary','John','Mel']
grades = [76,95,77,78,99]
GradeList = zip(names,grades)
df = pd.DataFrame(data = GradeList,
        columns=['Names','Grades'])
writer = pd.ExcelWriter('dataframe.xlsx', engine="xlsxwriter")
df.to_excel(writer, sheet_name="Sheet1")
writer.save()
Listing 2-12Exporting a Dataframe to Excel

如果你愿意,你可以将不同的数据帧保存到不同的工作表中,用一个.save()你将创建一个包含多个工作表的 Excel 文件(见清单 2-13 )。

writer = pd.ExcelWriter('dataframe.xlsx',engine='xlsxwriter')
df.to_excel(writer, sheet_name="Sheet1")
df2.to_excel(writer, sheet_name="Sheet2")
writer.save()
Listing 2-13Exporting Multiple Dataframes to Excel

Note

这假设您已经将另一个数据帧加载到df2变量中。

轮到你了

你能把清单 2-14 中的代码创建的数据帧导出到 Excel 吗?

import pandas as pd
names = ['Nike','Adidas','New Balance','Puma',’Reebok’]
grades = [176,59,47,38,99]
PriceList = zip(names,prices)
df = pd.DataFrame(data = PriceList, columns=['Names',’Prices’])
Listing 2-14Creating a Dataset for the Exercise

组合多个 Excel 文件中的数据

在前面的课程中,我们打开了单个文件,并将它们的数据放入单独的数据帧中。有时我们需要将几个 Excel 文件中的数据合并到同一个数据框架中。

我们可以用捷径或捷径来做这件事。先来看远路(列举 2-15 )。

  • 第 4 行:首先,让我们将all_data设置为一个空数据帧。
  • 第 6 行:将第一个 Excel 文件加载到 dataframe df中。
  • 第 7 行:将df的内容添加到数据帧all_data中。
  • 第 9 & 10 行:基本上与第 6 & 7 行相同,但用于下一个 Excel 文件。
import pandas as pd
import numpy as np

all_data = pd.DataFrame()

df = pd.read_excel("datasets/data1.xlsx")
all_data = all_data.append(df,ignore_index=True)

df = pd.read_excel("datasets/data2.xlsx")
all_data = all_data.append(df,ignore_index=True)

df = pd.read_excel("datasets/data3.xlsx")
all_data = all_data.append(df,ignore_index=True)
all_data.describe()

Listing 2-15Long Way

为什么我们称之为长路呢?因为如果我们加载一百个文件,而不是三个,这样做需要数百行代码。用我创业社区的朋友的话来说,就是规模不好。然而,最简单的方法是扩大规模。

现在,我们来看看捷径(列出 2-16 )。

  • 第 3 行:导入glob库。
  • 第 5 行:让我们将all_data设置为一个空的数据帧。
  • 第 6 行:这一行将遍历所有匹配模式的文件。
  • 第 7 行:将f中的 Excel 文件加载到数据框df中。
  • 第 8 行:将df的内容添加到数据帧all_data中。
import pandas as pd
import numpy as np
import glob

all_data = pd.DataFrame()
for f in glob.glob("datasets/data*.xlsx"):
    df = pd.read_excel(f)
    all_data = all_data.append(df,ignore_index=True)
all_data.describe()

Listing 2-16Short Way

因为我们只有三个数据文件,所以代码中的差异并不明显。然而,如果我们加载一百个文件,代码量的差异将是巨大的。这段代码将加载datasets目录中所有名称以data开头的 Excel 文件,不管有多少。

轮到你了

datasets/weekly_call_data文件夹中,有 104 个文件的两年每周通话数据。您的任务是尝试将所有数据加载到一个数据帧中。

从 SQL 加载数据

通常,我们的数据会以文件或数据库链接的形式出现。让我们学习如何从 sqlite 数据库文件中加载数据(清单 2-17 )。

import pandas as pd
from sqlalchemy import create_engine
# Connect to sqlite db
db_file = r'datasets/gradedata.db'
engine = create_engine(r"sqlite:///{}"
        .format(db_file))
sql = 'SELECT * from test'
        'where Grades in (76,77,78)'
sales_data_df = pd.read_sql(sql, engine)
sales_data_df
Listing 2-17Load Data from sqlite

这段代码创建了一个到名为gradedata.db的数据库文件的链接,并对其运行一个查询。然后,它将该查询产生的数据加载到名为sales_data_df的数据帧中。如果您不知道 sqlite 数据库中表的名称,您可以通过将 SQL 语句改为清单 2-18 中所示的语句来找到。

sql = "select name from sqlite_master"
    "where type = 'table';"
Listing 2-18Finding the Table Names

一旦您知道了您希望查看的表的名称(假设它是test),如果您想知道该表中字段的名称,您可以将您的 SQL 语句更改为清单 2-19 中所示的语句。

sql = "select * from test;"
Listing 2-19A Basic Query

然后,一旦您在数据帧上运行sales_data_df.head(),您将能够在每一列的顶部看到作为标题的字段。

和往常一样,如果您需要关于该命令的更多信息,您可以运行清单 2-20 中所示的代码。

sales_data_df.read_sql?
Listing 2-20Get Help on read_sql

轮到你了

你能从datasets/salesdata.db数据库加载数据吗?

将数据保存到 SQL

参见清单 2-21 中如何操作的示例。

import pandas as pd
names = ['Bob','Jessica','Mary','John','Mel']
grades = [76,95,77,78,99]
GradeList = zip(names,grades)
df = pd.DataFrame(data = GradeList,
    columns=['Names', 'Grades'])
df
Listing 2-21Create Dataset to Save

要将其导出到 SQL,我们可以使用清单 2-22 中所示的代码。

  • 第 14 行:mydb.db是您希望使用的 sqlite 数据库的路径和名称。
  • 第 18 行:mytable是数据库中表的名称。
import os
import sqlite3 as lite
db_filename = r'mydb.db'
con = lite.connect(db_filename)
df.to_sql('mytable',
    con,
    flavor='sqlite',
    schema=None,
    if_exists='replace',
index=True,
index_label=None,
chunksize=None,
dtype=None)
con.close()
Listing 2-22Export Dataframe to sqlite

和往常一样,如果您需要关于该命令的更多信息,您可以运行清单 2-23 中所示的代码。

df.to_sql?
Listing 2-23Get Help on to_sql

轮到你了

这可能有点棘手,但是您能创建一个包含在datasets/gradedata.csv中找到的数据的 sqlite 表吗?

随机数和创建随机数据

通常,您将使用本指南中的技术处理真实数据的数据集。但是,有时您需要创建随机值。

假设我们想随机列出婴儿的名字。我们可以如清单 2-24 所示开始。

import pandas as pd
from numpy import random
from numpy.random import randint
names = ['Bob','Jessica','Mary','John','Mel']
Listing 2-24Getting Started

首先,我们像往常一样导入我们的库。在最后一行,我们创建了一个我们将从中随机选择的名字列表。

接下来,我们添加清单 2-25 中所示的代码。

random.seed(500)
Listing 2-25Seeding Random Generator

这为随机数生成器提供了种子。如果你使用相同的种子,你会得到相同的“随机”数字。

我们将尝试这样做:

  1. randint(low=0,high=len(names))生成一个介于零和列表长度names之间的随机整数。
  2. names[n]选择其索引等于n的名称。
  3. for i in range(n)循环直到i等于n,即 1,2,3,…n
  4. random_names =从名称列表中随机选择一个名称,并重复n次。

我们将在清单 2-26 所示的代码中完成所有这些工作。

randnames = []
for i in range(1000):
    name = names[randint(low=0,high=len(names))]
    randnames.append(name)
Listing 2-26Selecting 1000 Random Names

现在我们有一个包含 1000 个随机名字的列表保存在我们的random_names变量中。让我们创建一个从 0 到 1000 的 1000 个随机数的列表(列表 2-27 )。

births = []
for i in range(1000):
    births.append(randint(low=0, high=1000))    
Listing 2-27Selecting 1000 Random Numbers

最后,将两个列表压缩在一起并创建 dataframe(清单 2-28 )。

BabyDataSet2 = list(zip(randnames,births))
df = pd.DataFrame(data = BabyDataSet2,
        columns=['Names', 'Births'])
df
Listing 2-28Creating Dataset from the Lists of Random Names and Numbers

轮到你了

创建一个名为parkingtickets的数据帧,它有 250 行,包含一个名称和一个 1 到 25 之间的数字。

三、准备数据是成功的一半

数据分析的第二步是清理数据。为分析工具准备数据可能是一项艰巨的任务。Python 和它的库试图让它尽可能简单。

只需几行代码,您就可以为分析准备好数据。你将能够

  • 清理数据;
  • 创建新变量;和
  • 组织数据。

清理数据

为了对大多数分析任务有用,数据必须是干净的。这意味着它应该是一致的、相关的和标准化的。在本章中,您将学习如何

  • 去除异常值;
  • 去除不合适的价值观;
  • 删除重复项;
  • 去掉标点符号;
  • 删除空白;
  • 标准化日期;和
  • 规范文本。

计算和移除异常值

假设你正在收集和你一起上高中的人的数据。如果你和比尔·盖茨是高中同学呢?现在,即使身家第二高的人只值 150 万美元,你们全班的平均水平也是被排名第一的亿万富翁推高的。通过查找异常值,您可以移除过高或过低的值,这些值会扭曲数据的整体视图。

我们介绍了两种检测异常值的主要方法:

  1. 标准差:如果数据是正态分布的,那么 95%的数据在平均值的 1.96 个标准差以内。因此,我们可以删除高于或低于该范围的值。
  2. 四分位数范围(IQR):IQR 是 25%分位数和 75%分位数之间的差值。任何低于 Q1 - 1.5 倍 IQR 或大于 Q3 + 1.5 倍 IQR 的值都被视为异常值并被移除。

让我们看看这些是什么样子的(清单 3-1 和 3-2 )。

  • 第 6 行:这里我们计算的上限等于标准差加上平均值的 1.96 倍。
  • 第 7 行:这里我们计算的下限等于平均值减去标准差的 1.96 倍。
  • 第 9 行:这里我们删除等级高于toprange的行。
  • 第 11 行:这里我们删除等级低于botrange的行。
import pandas as pd
Location = "datasets/gradedata.csv"
df = pd.read_csv(Location)
meangrade = df['grade'].mean()
stdgrade = df['grade'].std()
toprange = meangrade + stdgrade * 1.96
botrange = meangrade - stdgrade * 1.96
copydf = df
copydf = copydf.drop(copydf[copydf['grade']
        > toprange].index)
copydf = copydf.drop(copydf[copydf['grade']
        < botrange].index)
copydf
Listing 3-1Method 1: Standard Deviation 

  • 第 9 行:这里我们计算上限=第三个四分位数+1.5 * IQR。
  • 第 10 行:这里我们计算下边界=第一个四分位数-1.5 * IQR。
  • 第 13 行:这里我们删除等级高于toprange的行。
  • 第 14 行:这里我们删除等级低于botrange的行。
import pandas as pd
Location = "datasets/gradedata.csv"
df = pd.read_csv(Location)
q1 = df['grade'].quantile(.25)
q3 = df['grade'].quantile(.75)
iqr = q3-q1
toprange = q3 + iqr * 1.5
botrange = q1 - iqr * 1.5
copydf = df
copydf = copydf.drop(copydf[copydf['grade']
        > toprange].index)
copydf = copydf.drop(copydf[copydf['grade']
        < botrange].index)
copydf
Listing 3-2Method 2: Interquartile Range 

轮到你了

加载数据集datasets/outlierdata.csv。你能去除异常值吗?两种方法都试试。

Pandas 数据帧中的缺失数据

处理大型数据集最令人烦恼的事情之一就是寻找丢失的数据。这使得计算大多数聚合统计数据或生成数据透视表变得不可能或不可预测。如果您在一个 50 行的数据集中寻找缺失的数据点,这是相当容易的。然而,如果你试图在一个 500,000 行的数据集中找到一个缺失的数据点,那就困难多了。

Python 的pandas库具有帮助你查找、删除或更改缺失数据的功能(清单 3-3 )。

import pandas as pd
df = pd.read_csv("datasets/gradedatamissing.csv")
df.head()
Listing 3-3Creating Dataframe with Missing Data

前面的代码加载了一个合法的数据集,该数据集包含丢失数据的行。我们可以使用得到的数据帧来练习处理缺失数据。

要删除所有缺少(NaN)数据的行,使用清单 3-4 中所示的代码。

df_no_missing = df.dropna()
df_no_missing
Listing 3-4Drop Rows with Missing Data

要添加用空值填充的列,请使用清单 3-5 中的代码。

import numpy as np
df['newcol'] = np.nan
df.head()
Listing 3-5Add a Column with Empty Values

要删除只包含空值的任何列,请参见清单 3-6 。

df.dropna(axis=1, how="all")
Listing 3-6Drop Completely Empty Columns

要用零替换所有空值,请参见清单 3-7 。

df.fillna(0)
Listing 3-7Replace Empty Cells with 0

用等级的平均值填写缺失的等级,见清单 3-8 。

df["grade"].fillna(df["grade"].mean(), inplace=True)
Listing 3-8Replace Empty Cells with Average of Column

注意,inplace=True表示更改立即保存到数据帧。

要用每个性别的成绩平均值填写缺失的成绩,请参见清单 3-9 。

df["grade"].fillna(df.groupby("gender")
     ["grade"].transform("mean"), inplace=True)
Listing 3-9It's Complicated

我们也可以选择一些行,但忽略那些缺少数据点的行。要选择df中年龄不是 NaN 且性别不是 NaN 的行,请参见清单 3-10 。

df[df['age'].notnull() & df['gender'].notnull()]
Listing 3-10Selecting Rows with No Missing Age or Gender

轮到你了

加载数据集datasets/missinggrade.csv。如果你选择接受,你的任务就是删除缺失等级的行,并用该性别的平均值替换缺失的锻炼小时数。

过滤不适当的值

有时,如果您正在处理不是您自己收集的数据,您需要担心这些数据是否准确。见鬼,有时你需要担心这一点,即使是你自己收集的!检查每一个数据点的准确性可能很困难,但检查数据是否合适却很容易。

Python 的pandas库能够过滤掉不好的值(参见清单 3-11 )。

import pandas as pd

names = ['Bob','Jessica','Mary','John','Mel']
grades = [76,-2,77,78,101]

GradeList = zip(names,grades)
df = pd.DataFrame(data = GradeList,
    columns=['Names', 'Grades'])
df

Listing 3-11Creating Dataset

要删除等级过高的所有行,请参见清单 3-12 。

df.loc[df['Grades'] <= 100]
Listing 3-12Filtering Out Impossible Grades

要将越界值更改为最大或最小允许值,我们可以使用清单 3-13 中的代码。

df.loc[(df['Grades'] >= 100,'Grades')] = 100
Listing 3-13Changing Impossible Grades

轮到你了

使用本部分的数据集,您能否用零级替换所有的零下级?

查找重复行

如果你在使用别人的数据,你需要担心的另一件事是是否有任何数据是重复的。(相同的数据是被报告两次,还是被记录两次,还是仅仅被复制和粘贴?)见鬼,有时你需要担心这一点,即使你确实自己收集了它!检查每个数据点的准确性可能很困难,但检查数据是否重复却很容易。

Python 的pandas库不仅有查找重复行的功能,还有查找唯一行的功能(清单 3-14 )。

import pandas as pd
names = ['Jan','John','Bob','Jan','Mary','Jon','Mel','Mel']
grades = [95,78,76,95,77,78,99,100]
GradeList = zip(names,grades)
df = pd.DataFrame(data = GradeList,
        columns=['Names', 'Grades'])
df
Listing 3-14Creating Dataset with Duplicates

为了指出重复的行,我们可以简单地运行清单 3-15 中的代码。

df.duplicated()
Listing 3-15Displaying Only Duplicates in the Dataframe

为了显示没有重复的数据集,我们可以运行清单 3-16 中的代码。

df.drop_duplicates()
Listing 3-16Displaying Dataset without Duplicates

您可能会问,“如果整行都没有重复,但我仍然知道它是重复的,那该怎么办?”如果有人做你的调查或重新参加考试,就会发生这种情况,所以名称相同,但观察结果不同。在这种情况下,我们知道重复的名称意味着重复的条目,我们可以使用清单 3-17 中的代码。

df.drop_duplicates(['Names'], keep="last")
Listing 3-17Drop Rows with Duplicate Names, Keeping the Last Observation

轮到你了

加载数据集datasets/dupedata.csv。我们认为地址相同的人是重复的。你能在保留第一行的同时删除重复的行吗?

从列内容中删除标点符号

无论是电话号码还是地址,您经常会在数据中发现不需要的标点符号。让我们加载一些数据来看看如何解决这个问题(清单 3-18 )。

import pandas as pd
Location = "datasets/gradedata.csv"
## To add headers as we load the data...
df = pd.read_csv(Location)
df.head()
Listing 3-18Loading Dataframe with Data from CSV File

为了删除不需要的标点符号,我们创建了一个函数来返回所有不属于标点符号的字符,然后我们将这个函数应用到我们的数据帧中(清单 3-19 )。

import string
exclude = set(string.punctuation)
def remove_punctuation(x):
    try:
        x = ''.join(ch for ch in x if ch not in exclude)
    except:
        pass
    return x
df.address = df.address.apply(remove_punctuation)

df

Listing 3-19Stripping Punctuation from the Address Column

从列内容中删除空白

import pandas as pd
Location = "datasets/gradedata.csv"
## To add headers as we load the data...
df = pd.read_csv(Location)
df.head()
Listing 3-20Loading Dataframe with Data from CSV File

为了消除空白,我们创建了一个函数,它返回所有非标点符号的字符,然后我们将这个函数应用于我们的数据帧(清单 3-21 )。

def remove_whitespace(x):
    try:
        x = ''.join(x.split())
    except:
        pass
    return x
df.address = df.address.apply(remove_whitespace)

df

Listing 3-21Stripping Whitespace from the Address Column

标准化日期

整合不同来源的数据的一个问题是,不同的人和不同的系统可能会以不同的方式记录日期。也许他们用 1980 年 3 月 1 日,或者他们用 1980 年 3 月 1 日,甚至他们用 1980 年 1 月 3 日。即使它们都指向 1980 年 1 月 3 日,如果您在同一列中的不同格式之间来回切换,分析工具可能不会将它们都识别为日期(清单 3-22 )。

import pandas as pd
names = ['Bob','Jessica','Mary','John','Mel']
grades = [76,95,77,78,99]
bsdegrees = [1,1,0,0,1]
msdegrees = [2,1,0,0,0]
phddegrees = [0,1,0,0,0]
bdates = ['1/1/1945','10/21/76','3/3/90',
        '04/30/1901','1963-09-01']
GradeList = zip(names,grades,bsdegrees,msdegrees,
        phddegrees,bdates)
columns=['Names','Grades','BS','MS','PhD',"bdates"]
df = pd.DataFrame(data = GradeList, columns=columns)
df
Listing 3-22Creating Dataframe with Different Date Formats

清单 3-23 显示了一个将日期标准化为单一格式的函数。

from time import strftime
from datetime import datetime
def standardize_date(thedate):
    formatted_date = ""
    thedate = str(thedate)
    if not thedate or thedate.lower() == "missing"
                or thedate == "nan":
        formatted_date = "MISSING"
    if the_date.lower().find('x') != -1:
        formatted_date = "Incomplete"
    if the_date[0:2] == "00":
        formatted_date = thedate.replace("00", "19")
    try:
        formatted_date = str(datetime.strptime(    
        thedate,'%m/%d/%y')
.strftime('%m/%d/%y'))
    except:
        pass
    try:
        formatted_date = str(datetime.strptime(
thedate, '%m/%d/%Y')
.strftime('%m/%d/%y'))
    except:
        pass
    try:
        if int(the_date[0:4]) < 1900:
            formatted_date = "Incomplete"
        else:
            formatted_date = str(datetime.strptime(
            thedate, '%Y-%m-%d')
.strftime('%m/%d/%y'))
    except:
        pass
    return formatted_date
Listing 3-23Function to Standardize Dates

现在我们有了这个函数,我们可以将它应用到我们的数据帧上的birthdates列(清单 3-24 )。

df.bdates = df.bdates.apply(standardize_date)
df
Listing 3-24Applying Date Standardization to Birthdate Column

标准化文本,如 SSN、电话号码和邮政编码

整合来自不同来源的数据的一个问题是,不同的人和不同的系统可能会以不同的方式记录某些数据,如社会保险号、电话号码和邮政编码。也许他们在那些数字中使用连字符,也许他们没有。本节快速介绍了如何标准化这些类型的数据的存储方式(参见清单 3-25 )。

import pandas as pd
names = ['Bob','Jessica','Mary','John','Mel']
grades = [76,95,77,78,99]
bsdegrees = [1,1,0,0,1]
msdegrees = [2,1,0,0,0]
phddegrees = [0,1,0,0,0]
ssns = ['867-53-0909','333-22-4444','123-12-1234',
        '777-93-9311','123-12-1423']
GradeList = zip(names,grades,bsdegrees,msdegrees,
        phddegrees,ssns)
columns=['Names','Grades','BS','MS','PhD',"ssn"]
df = pd.DataFrame(data = GradeList, columns=columns)
df
Listing 3-25Creating Dataframe with SSNs

清单 3-26 中的代码创建了一个标准化 SSNs 的函数,并将其应用于我们的ssn列。

def right(s, amount):
    return s[-amount]
def standardize_ssn(ssn):
    try:
        ssn = ssn.replace("-","")
        ssn = "".join(ssn.split())
        if len(ssn)<9 and ssn != 'Missing':
            ssn="000000000" + ssn
            ssn=right(ssn,9)
    except:
        pass
    return ssn
df.ssn = df.ssn.apply(standardize_ssn)
df
Listing 3-26Remove Hyphens from SSNs and Add Leading Zeros if Necessary

创建新变量

一旦数据没有错误,您需要设置直接回答您的问题的变量。这是一个罕见的数据集,其中你需要回答的每个问题都直接由一个变量来解决。因此,您可能需要对变量进行大量的重新编码和计算,以准确获得您需要的数据集。

例子包括如下:

  • 创建 bin(比如将数字等级转换为字母等级,或者将日期范围转换为 Q1、Q2 等。)
  • 创建对另一列中的值进行排序的列
  • 创建一个列来指示另一个值已达到阈值(通过或失败、院长名单等)。)
  • 将字符串类别转换为数字(用于回归或相关)

宁滨数据

有时,您会有需要分组到箱中的离散数据。(想想:把数字成绩转换成字母成绩。)在这节课中,我们将学习宁滨(列表 3-27 )。

import pandas as pd
Location = "datasets/gradedata.csv"
df = pd.read_csv(Location)
df.head()
Listing 3-27Loading the Dataset from CSV

既然数据已经加载,我们需要定义 bin 和组名(清单 3-28 )。

# Create the bin dividers
bins = [0, 60, 70, 80, 90, 100]
# Create names for the four groups
group_names = ['F', 'D', 'C', 'B', 'A']
Listing 3-28Define Bins as 0 to 60, 60 to 70, 70 to 80, 80 to 90, 90 to 100

请注意,bin 值比group_names多一个。这是因为每个箱需要有一个顶部和底部限制。

df['lettergrade'] = pd.cut(df['grade'], bins,
        labels=group_names)
df
Listing 3-29Cut Grades

清单 3-29 基于bins列表对列grade进行分类,并使用group_names列表对值进行标记。

如果我们想计算每个类别的观察值,我们也可以这样做(清单 3-30 )。

pd.value_counts(df['lettergrade'])
Listing 3-30Count Number of Observations

轮到你了

从该部分重新创建数据帧,并创建一个列,将该行分类为通过或失败。这是一个硕士项目,要求学生达到 80 分或以上才能通过。

将函数应用于组、箱和列

我使用 Python 分析数据的首要原因是处理大于一百万行的数据集。第二个原因是对我的数据应用函数很容易。

为了看到这一点,首先我们需要加载一些数据(清单 3-31 )。

import pandas as pd
Location = "datasets/gradedata.csv"
df = pd.read_csv(Location)
df.head()
Listing 3-31Loading a Dataframe

from a CSV File

然后,我们用宁滨把数据分成字母等级(列表 3-32 )。

# Create the bin dividers
bins = [0, 60, 70, 80, 90, 100]
# Create names for the four groups
group_names = ['F', 'D', 'C', 'B', 'A']
df['letterGrades'] = pd.cut(df['grade'],
        bins, labels=group_names)
df.head()
Listing 3-32Using Bins

为了找到字母等级的平均学习时间,我们将我们的函数应用于 binned 列(列表 3-33 )。

df.groupby('letterGrades')['hours'].mean()
Listing 3-33Applying Function to Newly Created Bin

将一个函数应用于一个列看起来像清单 3-34 。

  • 第 1 行:让我们为数据帧中的每个等级获取一个整数值。
# Applying the integer function to the grade column
df['grade'] = df['grade'] = df['grade']
.apply(lambda x: int(x))
df.head()
Listing 3-34Applying a Function to a Column

对一个组应用一个函数可以在清单 3-35 中看到。

  • 第 1 行:创建一个分组对象。换句话说,创建一个表示特定分组的对象。在这种情况下,我们按性别对成绩进行分组。
  • 第 2 行:显示各团考前成绩的平均值。
gender_preScore = df['grade'].groupby(df['gender'])
gender_preScore.mean()
Listing 3-35Applying a Function to a Group

轮到你了

导入datasets/gradedata.csv文件并创建一个新的'status'入库列,作为通过(> 70)或失败(< =70)。然后,用passing'status'计算女学生的平均锻炼时间。

对数据行进行排序

查找具有最大值或最小值的行相对容易,但有时您希望为特定列查找具有 50 个最大值或 100 个最小值的行。这就是你需要排名的时候(列表 3-36 )。

import pandas as pd
Location = "datasets/gradedata.csv"
df = pd.read_csv(Location)
df.head()
Listing 3-36Load Data from CSV

如果我们想找到分数最低的行,我们需要按分数升序排列所有行。清单 3-37 显示了创建一个新列的代码,该列是 grade 值按升序排列的等级。

df['graderanked'] = df['grade'].rank(ascending=1)
df.tail()
Listing 3-37Create Column with Ranking by Grade

因此,如果我们只想查看分数最低的 20 名学生,我们将使用清单 3-38 中的代码。

df[df['graderanked'] < 21]
Listing 3-38Bottom 20 Students

为了按顺序查看它们,我们需要使用清单 3-39 中的代码。

df[df['graderanked'] < 6].sort_values('graderanked')
Listing 3-39Bottom 6 Students in Order

轮到你了

你能找到每周学习时间最多的 50 名学生吗?

基于条件创建列

有时,您需要根据一列或多列中的值对一行数据进行分类,例如根据分数是高于还是低于 70 来确定那些通过或未通过的学生。在本节中,我们将学习如何做到这一点(列出 3-40 )。

import pandas as pd
Location = "datasets/gradedata.csv"
df = pd.read_csv(Location)
df.head()
Listing 3-40Load Data from CSV

现在,假设我们想要一个指示学生是否不及格的列(清单 3-41 )。

  • 第 1 行:我们导入了numpy
  • 第 2 行:创建一个名为df.failing的新列,如果df.grade小于 70,则该列的值为 yes,否则为 no。
import numpy as np
df['isFailing'] = np.where(df['grade']<70,
'yes', 'no')
df.tail(10)
Listing 3-41Create Yes/No isFailing Column

相反,如果我们需要一个列来显示哪些男生分数不及格,我们可以使用清单 3-42 中的代码。

df['isFailingMale'] = np.where((df['grade']<70)
        & (df['gender'] == 'male'),'yes', 'no')
df.tail(10)
Listing 3-42Create Yes/No isFailingMale Column

轮到你了

如果一个学生每周锻炼超过三个小时,学习超过十七个小时,你能为timemgmt创建一个显示busy的列吗?

使用函数创建新列

我过去使用 Excel 做的大部分事情(也是我现在使用 Python 做的事情)是基于现有列创建新列。因此,使用下面的数据(列表 3-43 ,让我们看看我们将如何做。

import pandas as pd
Location = "datasets/gradedata.csv"
df = pd.read_csv(Location)
df.head()
Listing 3-43Load Data from CSV

为了创建一个包含每个学生全名的列,我们首先创建一个函数,从两个字符串中创建一个字符串(清单 3-44 )。

def singlename(fn, ln):
    return fn + " " + ln
Listing 3-44Create Function to Generate Full Name

现在,如果你测试这个函数,你会发现它可以很好地将亚当和斯密连接成亚当·斯密。然而,我们也可以将它与列选择器一起使用,使用我们的fnamelname列创建一个新列(清单 3-45 )。

df['fullname'] = singlename(df['fname'],df['lname'])
Listing 3-45Create Column to Hold the Full Name

这段代码创建了一个名为fullname的列,它连接了名字和姓氏。

轮到你了

你能创建一个名为total time的列,将每周的学习时间和锻炼时间加在一起吗?

将字符串类别转换为数字变量

为什么我需要将字符串类别转换为数字变量?许多分析工具不能处理文本,但是如果你把这些值转换成数字,事情就简单多了(清单 3-46 )。

import pandas as pd
Location = "datasets/gradedata.csv"
df = pd.read_csv(Location)
df.head()
Listing 3-46Load Data from CSV

方法 1:转换单个列来保存数字变量(清单 3-47 )。

def score_to_numeric(x):
    if x=='female':
        return 1
    if x=='male':
        return 0
Listing 3-47Function to Convert Gender to Number

现在,在您的列上运行该方法(清单 3-48 )。

df['gender_val'] = df['gender'].apply(score_to_numeric)
df.tail()
Listing 3-48Apply score_to_numeric Function to Gender

方法 2:创建单独的布尔列(清单 3-49 )。

df_gender = pd.get_dummies(df['gender'])
df_gender.tail()
Listing 3-49Create Boolean Columns Based on Gender Column

将列连接到原始数据集(清单 3-50 )。

# Join the dummy variables to the main dataframe
df_new = pd.concat([df, df_gender], axis=1)
df_new.tail()
# or
# Alterative for joining the new columns
df_new = df.join(df_gender)
df_new.tail()
Listing 3-50Add New Columns to Original Dataframe

轮到你了

使用datasets/gradesdatawithyear.csv,你能创建一个数字列来用数字 1 到 4 替换新生到高年级的状态吗?

组织数据

出于两个原因,原始变量和新创建的变量都需要正确格式化。

首先,我们的分析工具可以正确地与它们一起工作。未能正确格式化缺失值代码或虚拟变量将对您的数据分析产生重大影响。

第二,如果您不必一直查找 Q156 是哪个变量,那么运行分析和解释结果会快得多。

例子包括如下:

  • 删除不需要的列
  • 更改列名
  • 将列名改为小写
  • 将日期变量格式化为日期,等等。

删除和添加列

有时候我们需要调整数据。要么是遗漏了本应包含的内容,要么是遗漏了本应删除的内容。所以,让我们从清单 3-51 中的数据集开始。

import pandas as pd
names = ['Bob','Jessica','Mary','John','Mel']
grades = [76,95,77,78,99]
bsdegrees = [1,1,0,0,1]
msdegrees = [2,1,0,0,0]
phddegrees = [0,1,0,0,0]
GradeList = zip(names,grades,bsdegrees,msdegrees,
        phddegrees)
columns=['Names','Grades','BS','MS','PhD']
df = pd.DataFrame(data = GradeList, columns=columns)
df
Listing 3-51Creating Starting Dataset

我们可以通过简单地添加清单 3-52 中的代码来删除一列。

df.drop('PhD', axis=1)
Listing 3-52Dropping a Column

axis=1告诉drop我们想要删除一列(1)而不是一行(0)。

我们可以通过将新的列名设置为等于 0 来添加一个用零填充的列(清单 3-53 )。

df['HighSchool']=0
Listing 3-53Creating a New Column Filled with Zeros

但是,如果您想将新列设置为等于空值,您也可以这样做(清单 3-54 )。

df['PreSchool'] = np.nan
Listing 3-54Creating a New Column Filled with Null Values

现在,添加带有值的列并不困难。我们创建一个系列,并将列设置为等于该系列(清单 3-55 )。

d = ([0,1,0,1,0])
s = pd.Series(d, index= df.index)
df['DriversLicense'] = s
df
Listing 3-55Creating a New Column Filled with Values

轮到你了

你能删除bsmsphd学位栏吗?

可以加一个Hogwarts Magic Degree栏吗?除了杰西卡,每个人都有一个;这会让事情变得更难吗?没有吗?那我下次一定要难倒你。

选择列

您需要偶尔对数据进行部分选择,尤其是当数据集包含大量列时。在这里,我们学习如何创建一个只包含一些列的 dataframe(清单 3-56 )。

import pandas as pd
Location = "datasets/gradedata.csv"
df = pd.read_csv(Location)
df.head()
Listing 3-56Load Data from CSV

现在,为了选择一列数据,我们指定列名(清单 3-57 )。

df['fname']
Listing 3-57Selecting a Column into a List

但是,如果您运行该代码,您只能获得列中的数据(注意,标题丢失了)。这是因为它不返回 dataframe 它返回一个列表。为了在选择列时返回 dataframe,我们需要指定它(清单 3-58 )。

df[['fname']]
Listing 3-58Selecting a Column into a Dataframe

为了返回多列,我们使用清单 3-59 中的代码。

df[['fname','age','grade']]
Listing 3-59Selecting Multiple Columns into a Dataframe

当然,如果我们想要创建一个包含该列子集的 dataframe,我们可以将它复制到另一个变量中(清单 3-60 )。

df2 = df[['fname','age','grade']]
df2.head()
Listing 3-60Creating New Dataframe from Your Selection

轮到你了

我们需要创建一个邮件列表。能否通过选择名字、姓氏和地址字段来创建新的数据帧?

更改列名

有时你需要改变你的专栏的名字。有了pandas,很容易做到。首先,你加载你的数据(列表 3-61 )。

import pandas as pd

Location = "datasets/gradedata.csv"
df = pd.read_csv(Location)
df.head()

Listing 3-61Load Dataset from CSV

但是,当我们查看标题时,我们并不热衷于列名——或者说它没有任何列名。

更改列标题很简单(清单 3-62 )。

df.columns = ['FirstName', 'LastName', 'Gender',
        'Age', 'HoursExercisePerWeek',
        'HoursStudyPerWeek', 'LetterGrade',
        'StreetAddress']
df.head()
Listing 3-62Change All Headers

或者,如果您只想更改一两个值,您可以加载标题列表(清单 3-63 )。

headers = list(df.columns.values)
Listing 3-63Load List of Headers into a Temp Variable

一旦头被加载,你可以改变一些(清单 3-64 )。

headers[0] = 'FName'
headers[1] = 'LName'
df.columns = headers
df.head()
Listing 3-64Changing Headers

轮到你了

能不能把age列名改成years

将列名设置为小写

这可能不是世界上最大的问题,但是有时我需要将所有的列名转换成小写(或者大写)。本课将讲述如何做到这一点(列表 3-65 )。

import pandas as pd
Location = "datasets/gradedata.csv"
df = pd.read_csv(Location)
df.head()
Listing 3-65Load Data from CSV

一旦有了数据,有两种快速的方法将所有的列标题转换成小写(清单 3-66 )。

# method 1
df.columns = map(str.lower, df.columns)
# method 2
df.columns = [x.lower() for x in df.columns]
Listing 3-66Casting All Headers to Lowercase

轮到你了

你能想出如何让所有的列标题都大写吗?

查找匹配行

当然,您并不总是希望使用整个数据集进行计算。有时您希望只处理数据的子集。在这一课中,我们找出如何做到这一点(清单 3-67 )。

import pandas as pd
names = ['Bob','Jessica','Mary','John','Mel']
grades = [76,95,77,78,99]
GradeList = zip(names,grades)
df = pd.DataFrame(data = GradeList,
        columns=['Names', 'Grades'])
df
Listing 3-67Creating Dataset

要查找包含单词 Mel 的所有行,请在新的单元格中使用清单 3-68 中所示的代码。

df['Names'].str.contains('Mel')
Listing 3-68Filtering Rows

在执行完 Python 的这一行之后,您将看到一个布尔值列表——对于与我们的查询匹配的行为 True,对于不匹配的行为 False。

我们可以通过添加.any使我们的答案更简短。如果有任何一行匹配,这将只显示一个 True,如果没有一行匹配,则显示 False(清单 3-69 )。

# check if any row matches
df['Names'].str.contains('Mel').any()
Listing 3-69Check if Any Rows Match

或者,可以加上.all。如果所有行都匹配,这将只显示一个 True,如果至少有一行不匹配,则显示 False(列表 3-70 )。

# check if all rows match
df['Names'].str.contains('Mel').all()
Listing 3-70Check if All Rows Match

我们也可以将它与.loc (locate)函数一起使用,只显示符合特定标准的行(清单 3-71 )。

# Find the rows that match a criteria like this
df.loc[df['Names'].str.contains('Mel')==True]
# or even like this...
df.loc[df['Grades']==0]
Listing 3-71Show the Rows that Match

轮到你了

你能在下面的数据(列表 3-72 )中找到所有至少有一个 MS 学位的人吗?

import pandas as pd
names = ['Bob','Jessi','Mary','John','Mel','Sam',
        'Cathy','Hank','Lloyd']
grades = [76,95,77,78,99,84,79,100,73]
bsdegrees = [1,1,0,0,1,1,1,0,1]
msdegrees = [2,1,0,0,0,1,1,0,0]
phddegrees = [0,1,0,0,0,2,1,0,0]
GradeList = zip(names,grades,bsdegrees,msdegrees,
        phddegrees)
df = pd.DataFrame(data = GradeList, columns=['Name','Grade','BS','MS','PhD'])
df
Listing 3-72Starting Dataset

根据条件筛选行

import pandas as pd
Location = "datasets/gradedata.csv"
df = pd.read_csv(Location)
df.head()
Listing 3-73Load Data from CSV

我们可以显示一列数据(列表 3-74 )。

df['grade'].head()
Listing 3-74One Column

或者我们可以显示两列数据(清单 3-75 )。

df[['age','grade']].head()
Listing 3-75Two Columns

或者我们可以显示前两行数据(清单 3-76 )。

df[:2]
Listing 3-76First Two Rows

要显示等级大于 80 的所有行,请使用清单 3-77 中的代码。

df[df['grade'] > 80]
Listing 3-77All Rows with Grade > 80

使用多个条件有点棘手。因此,如果我们想要得到所有得分高于 99.9 且为男性的学生的列表,我们需要使用清单 3-78 中所示的代码。

df.ix[(df['grade'] > 99.9) &
    (df['gender'] == 'male') ]
Listing 3-78All Rows Where Men Scored > 99.9

相反,如果我们想要所有得分高于 99 的学生或者是女生,我们将需要使用清单 3-79 中的代码。

df.ix[(df['grade'] > 99) | (df['gender'] == 'female') ]
Listing 3-79All Rows Where Women or Scored > 99

轮到你了

你能显示学生是男性,每周锻炼少于两小时,每周学习超过十五小时的所有行吗?

基于条件选择行

import pandas as pd
Location = "datasets/gradedata.csv"
df = pd.read_csv(Location)
df.head()
Listing 3-80Load Data from CSV

  • 第 1 行:如果性别是女性,我们用 TRUE 创建一个变量。
  • 第 2 行:如果 grade 大于或等于 90,我们创建一个 TRUE 变量。
  • 第 3 行:这是我们选择所有性别均为女性且分数大于或等于 90 的案例的地方。
female = df['gender'] == "female"
a_student = df['grade'] >= 90
df[female & a_student].head()
Listing 3-81Method 1: Using Variables to Hold Attributes

df[df['fname'].notnull() & (df['gender'] == "male")]
Listing 3-82Method 2: Using Variable Attributes Directly

在清单 3-82 中,我们选择名字不缺失且性别为男性的所有情况。

轮到你了

你能找到学生每周锻炼四个小时或更多,学习十七个小时或更多,但成绩仍低于 80 分的所有行吗?

随机抽样数据框架

这个很简单。显然,有时我们有太大的数据集,我们需要取一个子集,所以让我们从一些加载的数据开始(清单 3-83 )。

import pandas as pd
import numpy as np
Location = "datasets/gradedata.csv"
df = pd.read_csv(Location)
df.tail()
Listing 3-83Load Dataset from CSV

为了从数据集中随机选择 100 行,我们可以简单地运行清单 3-84 中所示的代码。

df.take(np.random.permutation(len(df))[:100])
Listing 3-84Random Sample of 100 Rows from Dataframe

轮到你了

您能从该数据集中创建一个 500 行的随机样本吗?

四、寻找意义

数据分析的第三个阶段其实就是分析数据。如果没有合适的工具,很难在数据中找到意义。在这一节中,我们来看看 Python 用户可以使用的一些工具。

只需几行代码,您就能够进行以下分析:

  • 计算描述性统计
  • 相互关系
  • 线性回归
  • 数据透视表

计算聚合统计数据

正如您在上一章中可能已经看到的,使用describe很容易获得一些汇总统计数据。让我们看看如何直接找到这些值。

首先,让我们创建一些数据(清单 4-1 )。

import pandas as pd
names = ['Bob','Jessica','Mary','John','Mel']
grades = [76,95,77,78,99]
GradeList = zip(names,grades)
df = pd.DataFrame(data=GradeList,
        columns=['Names','Grades'])
df
Listing 4-1Creating Dataset for Statistics

一旦设置完成,我们就可以查看一些统计数据(清单 4-2 )。

df['Grades'].count()  # number of values
df['Grades'].mean()   # arithmetic average
df['Grades'].std()    # standard deviation
df['Grades'].min()    # minimum
df['Grades'].max()    # maximum
df['Grades'].quantile(.25)  # first quartile df['Grades'].quantile(.5)   # second quartile df['Grades'].quantile(.75)  # third quartile
Listing 4-2Computing Aggregate Statistics

Note

如果您试图同时执行一个单元格中的前一段代码,那么您只能看到.quantile()函数的输出。你必须一个一个地尝试。为了便于参考,我只是将它们组合在一起。好吗?

值得注意的是,平均值不是集中趋势的唯一衡量标准。其他措施见清单 4-3 。

# computes the arithmetic average of a column
# mean = dividing the sum by the number of values
df['Grades'].mean()
# finds the median of the values in a column
# median = the middle value if they are sorted in order
df['Grades'].median()
# finds the mode of the values in a column
# mode = the most common single value
df['Grades'].mode()
Listing 4-3Other Measures of Central Tendency

如果您需要计算标准差,您可能还需要方差(清单 4-4 )。

# computes the variance of the values in a column
df['Grades'].var()
Listing 4-4Computing Variance

最后,您不必指定计算统计数据的列。如果您只是对整个数据帧运行它,您将得到在所有适用的列上运行的函数(清单 4-5 )。

df.var()
Listing 4-5Computing Variance on All Numeric Columns

轮到你了

当然,在我们的数据集中,我们只有一列。尝试创建一个数据框架,并使用清单 4-6 中的数据集计算汇总统计数据。

names = ['Bob','Jessica','Mary','John','Mel']
grades = [76,95,77,78,99]
bsdegrees = [1,1,0,0,1]
msdegrees = [2,1,0,0,0]
phddegrees = [0,1,0,0,0]
Listing 4-6
Starting Dataset

计算匹配行的聚合统计信息

可以只计算符合特定标准的行的描述性统计数据。首先,让我们创建一些数据(清单 4-7 )。

import pandas as pd
names = ['Bob','Jessica','Mary','John','Mel']
grades = [76,95,77,78,99]
bs = [1,1,0,0,1]
ms = [2,1,0,0,0]
phd = [0,1,0,0,0]
GradeList = zip(names,grades,bs,ms,phd)
df = pd.DataFrame(data=GradeList,
        columns=['Name','Grade','BS','MS','PhD'])
df
Listing 4-7Creating Dataset

好了,我们已经介绍了如何找到匹配一组标准的行。我们还介绍了如何计算描述性统计数据,包括一次性计算和逐个计算。如果将这两者放在一起,您将能够找到符合特定标准的数据统计。

因此,要计算没有博士学位的人数,使用清单 4-8 中所示的代码。

df.loc[df['PhD']==0].count()
Listing 4-8Code for Computing Aggregate Statistics

您可以以同样的方式对单个列使用任何聚合统计函数。因此,要找出那些没有博士学位的人的平均成绩,使用清单 4-9 中的代码。

df.loc[df['PhD']==0]['Grade'].mean()
Listing 4-9Computing Aggregate Statistics on a Particular Column

轮到你了

用清单 4-10 的数据,硕士学历的人平均成绩是多少?

import pandas as pd
names = ['Bob','Jessica','Mary','John',
        'Mel','Sam','Cathy','Henry','Lloyd']
grades = [76,95,77,78,99,84,79,100,73]
bs = [1,1,0,0,1,1,1,0,1]
ms = [2,1,0,0,0,1,1,0,0]
phd = [0,1,0,0,0,2,1,0,0]
GradeList = zip(names,grades,bs,ms,phd)
df = pd.DataFrame(data=GradeList,
        columns=['Names','Grades','BS','MS','PhD'])
df
Listing 4-10Dataset for Exercise

分类数据

通常,我们以随机的顺序获取数据,但需要以完全不同的顺序使用数据。我们可以使用sort_values函数根据我们的需要重新排列我们的数据(清单 4-11 )。

import pandas as pd
Location = "datasets/gradedata.csv"
df = pd.read_csv(Location)
df.head()
Listing 4-11Loading Data from CSV

按年龄降序排列数据帧的行(清单 4-12 )。

df = df.sort_values(by='age', ascending=0)
df.head()
Listing 4-12Sorting by Age, Descending

先按学习时间,然后按锻炼时间,以升序对数据框的行进行排序(列表 4-13 )。

df = df.sort_values(by=['grade', 'age'],
        ascending=[True, True])
df.head()
Listing 4-13Sorting by Hours of Study and Exercise, Ascending

轮到你了

你能给数据框排序吗,先按名字,年龄,再按年级排序?

相互关系

相关性是一大类包含相关性的统计关系中的任何一种,尽管在通常的用法中,它通常指的是两个变量之间的线性关系的程度。依赖性现象的常见例子包括父母及其子女的身体状况之间的相关性,以及对产品的需求与其价格之间的相关性。

基本上,相关性衡量的是两个变量同向移动的紧密程度。高个子父母有高个子孩子?高度相关。戴着幸运帽,却很少打牌赢?相关性很小。随着生活水平的提高,你的储蓄水平会直线下降?高度负相关。

简单吧?

嗯,手工计算相关性可能有点困难,但在 Python 中是完全简单的(清单 4-14 )。

|   | 年龄 | 锻炼 | 小时 | 级别 | | :-- | :-- | :-- | :-- | :-- | | 年龄 | 1.000000 | -0.003643 | -0.017467 | -0.007580 | | 锻炼 | -0.003643 | 1.000000 | 0.021105 | 0.161286 | | 小时 | -0.017467 | 0.021105 | 1.000000 | 0.801955 | | 级别 | -0.007580 | 0.161286 | 0.801955 | 1.000000 |
import pandas as pd
Location = "datasets/gradedata.csv"
df = pd.read_csv(Location)
df.head()
df.corr()
Listing 4-14Running a Correlation

绝对值最高的交叉点是最相关的列。正值是正相关的,也就是说一起涨。负值是负相关的(一个上升,另一个下降)。当然,每一列都与自身完美相关。如你所见,学习时间和成绩高度相关。

轮到你了

从清单 4-15 中的代码加载数据,并找出相关性。

import pandas as pd
Location = "datasets/tamiami.csv"
Listing 4-15Load Data from CSV

回归

在统计建模中,回归分析是估计变量之间关系的统计过程。这是一种奇特的说法,我们使用回归来创建一个方程,该方程基于一个或几个自变量来解释因变量的值。让我们得到我们的数据(列表 4-16 ),

import pandas as pd
Location = "datasets/gradedata.csv"
df = pd.read_csv(Location)
df.head()
Listing 4-16Load Data from CSV

一旦我们有了这些,我们需要决定我们要对哪些列执行回归,以及哪个是因变量。我想试着根据年龄,运动时间,学习时间来预测成绩(列举 4-17 )。

import statsmodels.formula.api as sm
result = sm.ols(
        formula='grade ~ age + exercise + hours',
        data=df).fit()
result.summary()
Listing 4-17First Regression

第二行中的公式格式是您需要学习并轻松编辑的格式。它在波浪号(~)的左边显示了因变量,在右边显示了我们想要考虑的自变量。

如果您查看从汇总中获得的结果,R 平方表示数据中可以通过回归解释的变化的百分比。0.664,即 66.4%,不错,但还不够好。p 值(这里用P>|t|的值表示)表示自变量对因变量没有影响的概率。我喜欢让我的 p 值小于 5 %,所以唯一突出的变量是 59.5%的年龄。让我们重新运行回归,但是忽略年龄(列表 4-18 )。

import statsmodels.formula.api as sm
result = sm.ols(
        formula='grade ~ exercise + hours',
        data=df).fit()
result.summary()
Listing 4-18Second Regression

看看我们的新结果,我们没有改变我们的 R 平方,但我们已经消除了我们所有的高 p 值。所以,我们现在可以看看我们的系数,我们将得到一个类似于grade = 1.916 * hours of study +.989 * hours of exercise + 58.5316的方程。

轮到你了

创建一个新列,将性别转换为数值,如 1 表示女性,0 表示男性。你现在能把性别加入你的回归吗?这会提高你的 R 平方吗?

无截距回归

有时候,你的方程没有截距会更好。即使您的 p 值表明并非如此,这种情况也会发生。我总是尝试两种方法,就像理所当然的那样,看看 R 的平方是多少。要运行没有截距的回归,只需遵循清单 4-19 。

import pandas as pd
Location = "datasets/gradedata.csv"
df = pd.read_csv(Location)
df.head()
result = sm.ols(
        formula='grade ~ age + exercise + hours - 1', data=df).fit()
result.summary()
Listing 4-19Run Regression without Intercept

注意,是公式末尾的- 1告诉 Python 您希望消除截距。如果您查看结果,您会发现我们现在的 R 平方比上节课中的要高得多,并且我们也没有引起我们关注的 p 值。

轮到你了

尝试运行这些没有截距的简单回归:1。测试成绩和年龄之间的关系;2.测试成绩和锻炼之间的关系;第三。测试成绩和学习之间的关系。

如果只能选一个,你最喜欢哪个?

基本数据透视表

数据透视表(或交叉表)彻底改变了使用 Excel 进行分析的方式。然而,与 Excel 相比,我更喜欢 Python 中的数据透视表。我们来获取一些数据(列表 4-20 )。

import pandas as pd
Location = "datasets/gradedata.csv"
df = pd.read_csv(Location)
df.head()
Listing 4-20
Load Data

from CSV

最简单的是,为了得到一个数据透视表,我们需要一个数据帧和一个索引(清单 4-21 )。

pd.pivot_table(df, index=['gender'])
Listing 4-21Get Averages of All Numeric Columns Categorized by Gender

如您所见,pivot_table很聪明地假设我们想要所有数值列的平均值。如果我们只想指定一个值,我们可以这样做(清单 4-22 )。

| 性别 | 级别 | | :-- | :-- | | 女性的 | 82.7173 | | 男性的 | 82.3948 |
pd.pivot_table(df,
        values=['grade'],
        index=['gender'])
Listing 4-22
Average Grade by Gender

现在我们只看到按性别分类的平均成绩。然而,如果我们想的话,我们可以看看最小学习时间(列表 4-23 )。

| 性别 | 级别 | | :-- | :-- | | 女性的 | Two | | 男性的 | Zero |
pd.pivot_table(df,
        values=['grade'],
        index=['gender'],
        aggfunc='min')
Listing 4-23
Minimum Grade by Gender

我们还可以向索引中添加其他列。因此,要查看按性别和年龄分类的最高等级,我们只需运行清单 4-24 中的代码。

| 性别 | 年龄 | 小时 | | :-- | :-- | :-- | | 女性的 | Fourteen | Twenty | |   | Fifteen | Twenty | |   | Sixteen | Nineteen | |   | Seventeen | Twenty | |   | Eighteen | Twenty | |   | Nineteen | Twenty | | 男性的 | Fourteen | Nineteen | |   | Fifteen | Twenty | |   | Sixteen | Twenty | |   | Seventeen | Twenty | |   | Eighteen | Twenty | |   | Nineteen | Twenty |
pd.pivot_table(df,
        index=['gender','age'],
        aggfunc='max',
        values=['hours'])
Listing 4-24Max Grade by Gender and Age

我们也可以有多个值列。因此,为了按性别显示平均成绩和学习时间,我们可以运行清单 4-25 中的代码。

| 性别 | 级别 | 小时 | | :-- | :-- | :-- | | 女性的 | 82.7173 | Ten point nine three two | | 男性的 | 82.3948 | Eleven point zero four five |
pd.pivot_table(df,
        index=['gender'],
        aggfunc='mean',
        values=['grade','hours'])
Listing 4-25
Average Grade and Hours by Gender

我们还可以对数据子集执行数据透视表。首先,选择您的数据,然后对该选择进行标准透视。因此,为了显示 17 岁学生的平均成绩和学习时间,我们可以运行清单 4-26 中的代码。

| 性别 | 级别 | 小时 | | :-- | :-- | :-- | | 女性的 | 83.599435 | 10.943503 | | 男性的 | 82.949721 | 11.268156 |
df2 = df.loc[df['age'] == 17]
pd.pivot_table(df2,
        index=['gender'],
        aggfunc='mean',
        values=['grade','hours'])
Listing 4-26
Average Grade and Hours by Gender

最后,我们可以在 Python 数据透视表中包含总计,如清单 4-27 所示。

| 性别 | 级别 | 小时 | | :-- | :-- | :-- | | 女性的 | 83.599435 | 10.943503 | | 男性的 | 82.949721 | 11.268156 | | 全部 | 83.272753 | 11.106742 |
df2 = df.loc[df['age'] == 17]
pd.pivot_table(df2,
        index=['gender'],
        aggfunc='mean',
        values=['grade','hours'],
        margins='True')
Listing 4-27
Average Grade and Hours by Gender

轮到你了

你能创建一个数据透视表来显示锻炼超过两个小时的人的性别平均分吗?

五、可视化数据

数据质量报告

当您查看了足够多的数据集后,您将开发一组您想要回答的关于数据的问题,以确定数据集有多好。下面的脚本组合起来形成了一个数据质量报告,我用它来评估我所处理的数据集。

# import the data
import pandas as pd
Location = "datasets\gradedata.csv"
df = pd.read_csv(Location)
df.head()
df.mode().transpose()

Listing 5-1Load Dataset from CSV

data_types = pd.DataFrame(df.dtypes,
        columns=['Data Type'])
data_types

Listing 5-2Finding Data Types of Each Column

missing_data_counts = pd.DataFrame(df.isnull().sum(),
        columns=['Missing Values'])
missing_data_counts

Listing 5-3Counting Number of Missing Observations by Column

present_data_counts = pd.DataFrame(df.count(),
        columns=['Present Values'])
present_data_counts

Listing 5-4Counting Number of Present Observations by Column

unique_value_counts = pd.DataFrame(
        columns=['Unique Values'])
for v in list(df.columns.values):
        unique_value_counts.loc[v] = [df[v].nunique()]
unique_value_counts

Listing 5-5Counting Number of Unique Observations by Column

minimum_values = pd.DataFrame(columns=[
        'Minimum Values'])
for v in list(df.columns.values):
        minimum_values.loc[v] = [df[v].min()]
minimum_values

Listing 5-6Finding the Minimum Value for Each Column

maximum_values = pd.DataFrame(
        columns=['Maximum Values'])
for v in list(df.columns.values):
        maximum_values.loc[v] = [df[v].max()]
maximum_values

Listing 5-7Finding the Maximum Value for Each Column

pd.concat([present_data_counts,
        missing_data_counts,
        unique_value_counts,
        minimum_values,
        maximum_values],
        axis=1)

Listing 5-8Joining All the Computed Lists into 1 Report 

轮到你了

能否为datasets/tamiami.csv数据集创建数据质量报告?

绘制数据集:线形图

要创建一个简单的线图,输入清单 5-9 中的代码。

import pandas as pd
names = ['Bob','Jessica','Mary','John','Mel']
grades = [76,83,77,78,95]
GradeList = zip(names,grades)
df = pd.DataFrame(data = GradeList,
        columns=['Names', 'Grades'])
%matplotlib inline
df.plot()

Listing 5-9Line Plotting Your Dataset

当您运行它时,您应该会看到类似图 5-1 的图形。

A463663_1_En_5_Fig1_HTML.jpg

图 5-1

Simple Line Plot

定制图形很容易,但是您需要首先添加matplotlib库。

将清单 5-10 中的代码添加到您已经做的代码中。

import matplotlib.pyplot as plt
df.plot()
displayText = "my annotation"
xloc = 1
yloc = df['Grades'].max()
xtext = 8
ytext = 0
plt.annotate(displayText,
            xy=(xloc, yloc),
            xytext=(xtext,ytext),
            xycoords=('axes fraction', 'data'),
            textcoords='offset points')

Listing 5-10Code to Plot a Customized Graph

好的,annotate命令有很好的文档,位于 http://matplotlib.org/api/pyplot_api.html 。但是让我们来看看我们输入的内容:

  • displayText:我们要为这个注释显示的文本
  • xloc, yloc:我们要标注的数据点的坐标
  • xtext, ytext:使用textcoords中指定的坐标系,我们希望文本出现的位置的坐标
  • xycoords:设置用于查找数据点的坐标系;它可以为 x 和 y 分别设置
  • textcoords:设置用于放置文本的坐标系

最后,我们可以添加一个箭头,将标注的数据点链接到文本标注(清单 5-11 )。

df.plot()
displayText = "my annotation"
xloc = 1
yloc = df['Grades'].max()
xtext = 8
ytext = -150     
plt.annotate(displayText,
            xy=(xloc, yloc),
            arrowprops=dict(facecolor='black',
                        shrink=0.05),   
            xytext=(xtext,ytext),
            xycoords=('axes fraction', 'data'),
            textcoords='offset points')

Listing 5-11Code to Plot a Customized Graph

我们所做的只是调整文本的偏移量,以便在数据和注释之间有足够的空间来实际看到箭头。我们通过将ytext值从 0 更改为-150 来实现这一点。然后,我们添加了箭头的设置。

关于创建箭头的更多信息可以在 http://matplotlib.org/users/annotations_intro.htmlannotate文档页面上找到。

轮到你了

以我们在这个例子中使用的相同数据集为例,向 Bob 的 76 添加一个注释“哇!”

绘制数据集:条形图

要创建条形图,输入清单 5-12 中的代码。

import matplotlib.pyplot as plt
import pandas as pd
names = ['Bob','Jessica','Mary','John','Mel']
status = ['Senior','Freshman','Sophomore','Senior',
        'Junior']
grades = [76,95,77,78,99]
GradeList = zip(names,grades)
df = pd.DataFrame(data = GradeList,
        columns=['Names', 'Grades'])
%matplotlib inline
df.plot(kind='bar')

Listing 5-12Bar Plotting Your Dataset

一旦您运行它,您将得到一个简单的条形图,但是 x 轴上的标题是数字 0–4。

A463663_1_En_5_Fig2_HTML.jpg

图 5-2

Simple Bar Plot

但是如果我们将Names列转换成索引,我们可以改进这个图。因此,首先,我们需要添加清单 5-13 中的代码。

df2 = df.set_index(df['Names'])
df2.plot(kind="bar")

Listing 5-13Adding Code to Plot Your Dataset

然后我们会得到一个类似图 5-3 的图。

A463663_1_En_5_Fig3_HTML.jpg

图 5-3

Bar Plot with Axis Titles

轮到你了

您能更改代码来创建一个状态为标签的条形图吗?

绘制数据集的图形:箱形图

要创建一个方框图,输入清单 5-14 中的代码。

import matplotlib.pyplot as plt
import pandas as pd
%matplotlib inline
names = ['Bob','Jessica','Mary','John','Mel']
grades = [76,95,77,78,99]
gender = ['Male','Female','Female','Male','Female']
status = ['Senior','Senior','Junior','Junior','Senior']
GradeList = zip(names,grades,gender)
df = pd.DataFrame(data = GradeList, columns=['Names', 'Grades', 'Gender'])
df.boxplot(column='Grades')

Listing 5-14Box Plotting Your Dataset

一旦你运行它,你会得到一个简单的方框图。

A463663_1_En_5_Fig4_HTML.jpg

图 5-4

Simple Box Plot

现在,我们可以使用一个命令来创建分类图(在本例中,按性别分类)。见列表 5-15 。

df.boxplot(by='Gender', column="Grades")

Listing 5-15Adding Code to Categorize Your Box Plot

然后我们会得到一个类似图 5-5 的图。见清单 5-16 。

A463663_1_En_5_Fig5_HTML.jpg

图 5-5

Categorized Box Plot .

清单 5-16。分类箱线图

最后,为了调整 y 轴,使其从 0 到 100,我们可以运行清单 5-17 中的代码。

axis1 = df.boxplot(by='Gender', column="Grades")
axis1.set_ylim(0,100)

Listing 5-17Adding Code to Adjust the Y-axis

它将产生一个类似于图 5-6 的图形。

A463663_1_En_5_Fig6_HTML.jpg

图 5-6

Box Plot Grouped by Gender

轮到你了

使用我们刚刚创建的数据集:

  • 你能创建一个按学生身份分类的成绩方框图吗?
  • 你能创建一个 y 轴从 50 到 110 的箱形图吗?

绘制数据集图表:直方图

由于直方图的性质,我们确实需要比我们正在处理的示例数据集中更多的数据。输入清单 5-18 中的代码来导入更大的数据集。

import matplotlib.pyplot as plt
import pandas as pd
%matplotlib inline
Location = "datasets/gradedata.csv"
df = pd.read_csv(Location)
df.head()

Listing 5-18Importing Dataset from CSV File

为了创建一个简单的直方图,我们可以简单地添加清单 5-19 中的代码。

A463663_1_En_5_Fig7_HTML.jpg

图 5-7

Simple Histogram

df.hist()

Listing 5-19Creating a Histogram not Creating a Box Plot

因为pandas不确定您希望对哪一列的值进行计数,所以它给出了所有列的直方图和数值。

为了只查看几个小时的柱状图,我们可以将其指定为清单 5-20 。

A463663_1_En_5_Fig8_HTML.jpg

图 5-8

Single Column Histogram

df.hist(column="hours")

Listing 5-20Creating Histogram for Single Column

为了查看按性别划分的时间直方图,我们可以使用清单 5-21 。

A463663_1_En_5_Fig9_HTML.jpg

图 5-9

Categorized Histogram

df.hist(column="hours", by="gender")

Listing 5-21Categorized Histogram

轮到你了

你能创建一个按性别分类的年龄直方图吗?

绘制数据集图表:饼图

要创建一个饼图,输入清单 5-22 中的代码。

import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
names = ['Bob','Jessica','Mary','John','Mel']
absences = [3,0,1,0,8]
detentions = [2,1,0,0,1]
warnings = [2,1,5,1,2]
GradeList = zip(names,absences,detentions,warnings)
columns=['Names', 'Absences', 'Detentions','Warnings']
df = pd.DataFrame(data = GradeList, columns=columns)
df

Listing 5-22Pie Charting Your Dataset

这段代码创建了一个违反学生规则的数据集。接下来,在一个新的单元格中,我们将创建一个列来显示每个学生的违规或违规总数(列表 5-23 )。

df['TotalDemerits'] = df['Absences'] +
        df['Detentions'] + df['Warnings']
df

Listing 5-23Creating New Column

最后,为了实际创建一个记过次数的饼图,我们可以运行清单 5-24 中的代码。

plt.pie(df['TotalDemerits'])

Listing 5-24Creating Pie Chart of Demerits

一旦你运行它,你会得到一个简单的饼状图(图 5-10 )。

A463663_1_En_5_Fig10_HTML.jpg

图 5-10

Simple Pie Chart

但是由于它有点简单(而且有点长),让我们在一个新的单元格中尝试清单 5-25 中的代码。

  • 第 2 行:这将学生的名字作为标签添加到饼图中。
  • 第 3 行:这是为第五个学生展开的饼图。你可以根据自己的喜好增加或减少数量。
  • 第 4 行:这就是将饼图旋转到不同点的原因。
  • 第 5 行:这是饼图上数字标签的格式。
  • 第 7 行:这是迫使饼图呈圆形的原因。
plt.pie(df['TotalDemerits'],
       labels=df['Names'],
       explode=(0,0,0,0,0.15),
       startangle=90,
       autopct='%1.1f%%',)
plt.axis('equal')
plt.show()

Listing 5-25Creating a Customized Pie Chart

你会看到一个类似图 5-11 的饼状图。

A463663_1_En_5_Fig11_HTML.jpg

图 5-11

Customized Pie Chart

轮到你了

如果我们不突出最差的学生,而是突出最好的学生,会怎么样?让我们旋转图表并更改设置,以便突出显示 John 而不是 Mel。

绘制数据集:散点图

清单 5-26 中的代码将允许我们生成一个简单的散点图。

  • 第 4 行:指定数字应该内嵌显示
  • 第 6 行:生成一个包含 200 个值的随机数据集
  • 第 7 行:使用数据帧的索引作为 x,使用列Col的值作为 y,创建一个散点图
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
dataframe = pd.DataFrame({'Col':
        np.random.normal(size=200)})
plt.scatter(dataframe.index, dataframe['Col'])

Listing 5-26Creating a Scatter Plot

你应该得到一个类似图 5-12 的图。

A463663_1_En_5_Fig12_HTML.jpg

图 5-12

Simple Scatterplot

看我们的图,数据似乎没有任何模式。是随机的!

轮到你了

datasets/gradedata.csv中创建小时和等级数据的散点图。你看到数据中的模式了吗?

六、练习

在这一章中,你会发现一些你可以用来练习你所学知识的问题。随意使用你所学的任何技巧,但不要全部使用。那就太夸张了。玩得开心,祝你好运!

分析练习 1

对于本练习,您可以在datasets/algebradata.csv中找到数据。

弗兰克·马利格鲁是华盛顿 DC 公立学校的代数协调员。学校董事会要求他收集一些统计数据。使用关于他的班级的信息,计算以下内容:

  1. 成绩及格的学生百分比
  2. 及格的妇女百分比
  3. 所有学生的平均学习时间
  4. 及格学生的平均学习时间

分析练习 2

你可以在datasets/axisdata文件中找到数据。

卡洛斯·胡根斯是安讯士汽车销售公司的销售经理,这是一家低成本的二手车区域连锁店。Carlos 正在为他的年度销售会议做准备,并且正在寻找提高销售团队业绩的最佳方法。他的数据包括每个团队成员的性别、经验年限、销售培训和每周工作时间。它还包括每个销售人员每月售出的平均汽车数量。找出以下内容:

  1. 平均每月售出的汽车
  2. 每月售出的最大汽车数量
  3. 每月售出的最小汽车数
  4. 按性别分列的每月平均汽车销量
  5. 每月销售三辆以上汽车的人的平均工作时间
  6. 平均经验年限
  7. 每月销售三辆以上汽车的人的平均经验年限
  8. 每月售出的平均汽车数量,按是否接受过销售培训排序

你认为衡量一个人是否是优秀销售人员的最佳指标是什么?

分析练习 3

数据可以在datasets/dvddata.xlsx中找到。

鲍姆加特纳 DVD 公司在全国销售高质量的 DVD 复制器。你刚刚被提升为销售经理,负责分析销售趋势,并就未来处理销售的最佳方式做出决策。

现在,您的每个销售人员都负责同一地区的一个或多个地区。你的销售人员通过电子邮件、电话或办公室拜访来联系他们的客户。每封邮件大约需要一分钟。每个电话大约需要二十分钟,拜访办公室大约需要两个小时。你的员工每周工作 40 小时。

  1. 计算沟通方式对一个月内售出的复印机数量的影响。
  2. 建立一个模型,在给定客户数量和每种沟通模式频率的情况下,预测销售数量。

分析练习 4

数据可以在datasets/tamiami.xlsx中找到。

来自迈阿密的塔米想在纽约市开一家墨西哥餐车。她已经知道了自己的费用,但是不知道收什么。她能够获得纽约市各区热狗推车的日平均销售数据。分析这些数据,找出价格和销售量之间的关系。你可以用这种关系作为人们愿意花多少钱吃一顿快餐的基准。您需要提供以下信息:

  1. 影响销售的其他相关因素(除价格外)列表(如果有)
  2. 销售数量的等式

分析项目

数据可以在datasets/southstyle.xlsx中找到。

总部位于南卡罗来纳州的 SouthStyle 食品公司是一家领先的香肠制造商,过去 40 年来一直以 SouthStyle 品牌销售其产品。SouthStyle Foods 从事高品质南方风味加工食品的生产和营销,如香肠、培根、hoppin' john、羽衣甘蓝等。该公司根据现代消费者的要求和喜好,提供传统南方风味的完美融合。它结合了更好的味道与天然纯度,创新的包装,和对健康的关怀,价格合理。

凭借优质的食品产品和对客户满意度的关注,SouthStyle Foods 通过扩大其客户群并在南卡罗来纳州和全国范围内以可承受的价格提供其产品,在加工食品领域保持领先地位。作为其举措的一部分,该公司计划扩大其业务,以增加其产品在其他地区的销售。然而,对于这一点,该公司希望了解能够提高不同州之间销售额的因素。然而,随着一些新公司的出现,该公司最近目睹了整个行业竞争的加剧,导致其销售额下降。

为了讨论这些问题,总裁阿什利·西尔斯召集公司的高级官员开会。在一次相当热烈的讨论中,他们讨论了许多导致销售额下降的因素。然而,没有出现共同因素。营销副总裁建议聘请一位有商业研究经验的顾问,大家都同意了。

南方食品公司雇佣了你的市场调查机构 Care Research 来做这项工作。听完这个问题后,你的老板想到对这个问题进行横截面分析,因为它必须从 30 个地区收集数据。根据公司的说法,你的公司开始识别可能对销售产生影响的变量。根据收集到的信息(附件一)和之前的研究,你提出了五个重要变量,预计这些变量对确定销售额至关重要。这些变量是该地区的市场潜力、销售加工食品的商店数量、经纪人数量、该地区受欢迎品牌的数量以及该地区的人口数量。营销副总裁想知道应该关注的最重要的因素。他还想知道未来可能的需求。

必需的交付物

  1. 确定南方食品需要关注的最重要的因素。
  2. 创建一个公式或模型,允许 SouthStyle Foods 在进入新领域时预测其销售额。

标签:数据分析,Python,手册,df,pd,Listing,清单,import,数据
From: https://www.cnblogs.com/apachecn/p/18443315

相关文章

  • Python-自然语言处理应用指南-全-
    Python自然语言处理应用指南(全)原文:AppliedNaturalLanguageProcessingwithPython协议:CCBY-NC-SA4.0一、什么是自然语言处理?深度学习和机器学习继续在各个行业中扩散,并彻底改变了我希望在本书中讨论的主题:自然语言处理(NLP)。NLP是计算机科学的一个子领域,致力于让计......
  • Java-人工智能初学者实用手册-全-
    Java人工智能初学者实用手册(全)零、前言在一切都由技术和数据驱动的现代世界中,人工智能变得越来越重要,它是使任何系统或流程自动化的过程,以自动执行复杂的任务和功能,从而实现最佳生产率。面向初学者的Java人工智能实践解释了使用流行的基于Java的库和框架来构建智能应用程......
  • JOOQ-入门手册-全-
    JOOQ入门手册(全)原文:BeginningjOOQ协议:CCBY-NC-SA4.0一、欢迎使用jOOQ我15岁开始从事软件工程(实际上,是严肃的计算机业务),使用Oracle8iSQL。是的,从技术上来说,我从小就是个老人了。在我开始上大学之前,玩SQL*Plus,尝试(并失败)我的第一次OracleSQL认证考试,教会了......
  • python 包含有引号和花括号的字符串的格式化
    replace不起作用;update_per_seconds="30"uploadtime_per_seconds="30"imei_string="1234"###采用{0}format不行###下面replace不行msg="""{"rmtcmd":"set","dev":{"poll":{&......
  • (开题)flask框架股票模拟交易系统的设计与实现(程序+论文+python)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着金融市场的不断发展和互联网的普及,股票交易已成为许多人投资理财的重要手段。然而,股票市场的复杂性和风险性使得许多投资者在实际操作......
  • python - 合理的入门编程语言
    盗版资源我就一个人独享了,分享的大部分为“开源”,不小心则为侵权。当两国战争后,谁在乎“侵权”?编程语言心法参考:http://www.yinwang.org/blog-cn/2017/07/06/master-pl英语阅读速成:http://www.yinwang.org/blog-cn/2018/11/23/grammar文档部分:教程https://docs.python.org/3......
  • 计算机毕业设计 基于Python的摄影平台交流系统的设计与实现 Python+Django+Vue 前后端
    ......
  • 计算机毕业设计 基于Python的新闻采集与订阅平台的设计与实现 Python+Django+Vue 前后
    ......
  • 基于nodejs+vue学生网课学习数据分析与展示系统[开题+源码+程序+论文]计算机毕业设计
    本系统(程序+源码+数据库+调试部署+开发环境)带文档lw万字以上,文末可获取源码系统程序文件列表开题报告内容研究背景随着互联网技术的飞速发展和全球疫情的持续影响,在线教育已成为教育领域的重要组成部分。各大教育平台纷纷推出网课服务,以满足广大学生在家学习的需求。然而,......
  • 基于python+flask框架的咸鱼平台(开题+程序+论文) 计算机毕设
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着互联网技术的飞速发展,电子商务已经成为人们日常生活的重要组成部分。在众多电商平台中,二手交易平台以其独特的定位和市场需求,逐渐崭露......