第六节 散点图

在上一节中,我们看到了一个散点图的例子,它可以使我们看到两组数字之间存在相关性的初步迹象。在本节中,我们将通过查看包含4组数据的数集来分析散点图的重要性。对于这个数据集,传统的统计量结果都是相同的,但每个数据集的散点图显示出重要的差异。

首先来看看如何在Python中创建一个散点图:


>>> x = [1, 2, 3, 4] >>> y = [2, 4, 6, 8] >>> import matplotlib.pyplot as plt >>> plt.scatter(x, y) <matplotlib.collections.PathCollection object at 0x000001A8088089E8> >>> plt.show()


scatter()函数用于在两个数字列表x与y之间创建一个散点图。这个图与我们第二章学到的绘制图形相比较,唯一的区别在于不使用plot()函数,而是使用scatter()。同样,必须调用show()函数来显示图形。

要了解更多散点图的信息,我们来看一个重要的统计学研究:统计学家Francis Anscombe 的统计分析图。该研究考察了4各不同的数据集,称为Anscombe四重奏,他们具有相同的属性:均值,方差和相关系数。

数据集如下表所示(从原始研究转载)。

python中数学统计方法(Python数学编程第三章)(1)

Anscombe四重奏

我们分别将(X1,Y1)、(X2,Y2)、(X3,Y3)和(X4,Y4)称为数据集A、B、C和D。下表显示了四舍五入到两位小数的数据集统计量。

python中数学统计方法(Python数学编程第三章)(2)

Anscombe四重奏的统计量

各个数据的散点图如图所示。

python中数学统计方法(Python数学编程第三章)(3)

Anscombe四重奏的散点图

如果我们仅仅看传统的统计量,如均值、标准差和相关系数,这些数据集几乎是完全相同的。但散点图显示这些数据实际上差异非常大。因此,散点图是一个重要工具,在得出数据集的任何结论之前,他应该与其他统计量一起使用。

第七节 从文件中读取数据

在本章的所有程序中,我们在计算中使用的数字列表都是自己输入到程序中的。如果你想计算不同数据集的统计量,你必须在程序中输入整个新的数据集。还学习了如何使程序提示用户输入数据并将输入的数据作为输入参数,但是对于大数据集,让用户在每次使用该程序时都输入长的数字列表并不方便。 更好的选择是从文件中读取用户数据。我们来看一个简单的例子,介绍如何从文件中读取数字并对其执行数学运算。首先,我将演示如何从一个简单的文本文件 中读取数据,文件的每一行包含-一个新的数据元素。然后,我将向你展示如何从以 csv格式存储数据的文件中读取数据,这将拓展很多应用,因为有大量有用的数据 集可以通过CSV格式从网上下载。

3.7.1 从文本文件中读取数据

我们先来看一个文件mydata.txt,它包含我们在本章一开始就讲解的捐赠列表(一行一个数字)


100 60 70 900 100 200 500 500 503 600 1000 1200


以下程序将读取该文件并输出文件中存储的数字的总和。


# find the sum of numbers stored in a file def sum_data(filename): s = 0 with open(filename) as f: for line in f: s = float(line) print('Sum of the numbers : {0}'.format(s)) if __name__ == '__main__': sum_data('mydata.txt')


首先打开filename指定的文件,并逐行读取(f为文件的对象,你可以使用它来指代打开的文件)。打开后将里面的每行数据转为浮点数,然后相加求和,直到读取完所有的数据。最后一个数据(标签为s)包含数字的总和并在执行结束时输出

运行程序前,在.py文件同目录下需要有一个名为”mydata.txt“文件,其中数据内容为上述刚刚提到的捐款清单,运行程序:


Sum of the numbers : 5733.0


本章中的所有程序都是从列表中读取数据。要读取文件中的数据并且复用之前的代码,我们可以将文件中的数据读取出来然后创建一个列表来存储数据,然后既可以使用之前的代码啦。以下程序可以计算存储在mydata.txt文件中数字均值:


''' Calculating the mean of numbers stored in a file ''' def read_data(filename): numbers = [] with open(filename) as f: for line in f: numbers.append(float(line)) return numbers def calculate_mean(numbers): return sum(numbers) / len(numbers) if __name__ == '__main__': numbers = read_data('mydata.txt') mean = calculate_mean(numbers) print('Mean : {0}'.format(mean))


可以看到,我们在调用calculate_mean()函数之前,先把文件中的数据读取出来,转成浮点数后存储到一个列表中,然后传入calcula_mean()函数进行求均值,剩下的部分之前已经说过,此处不再赘述。

运行程序:


Mean : 477.75


对于mydata.txt里面的数据,大家可以多做一些修改来试试。

当然也可以做一些修改,就是可以让用户输入输出文件名称,这样用户就可以指定数据文件。

3.7.2 从CSV文件中读取数据

如果把一个csv文件使用记事本打开的话,我们就可以看到,csv文件值之间使用逗号分隔,也就是列和列之间用逗号分隔。

以下是一个csv文件样本,其中包含几个数字以及他们的平方。


Number,Squared 10,100 9,81 22,484


第一行为列名称。在本例中告诉我们,第一列为数字,第二列为他们的平方。接下来包括三行数据,每行的值之间使用逗号隔开。可以使用类似于.txt文件的读取方式来读取数据。但是,Python的标准库有一个用于读取(和写入)csv文件的专用模块(csv),这个模块可以让读取变得更容易一些。

将以上数据保存到名为numbers.csv文件中,并与程序放到同一目录下。以下程序演示了如何让读取此文件,然后创建一个散点图来显示数字与其平方值。


import csv import matplotlib.pyplot as plt def scatter_plot(x, y): plt.scatter(x, y) plt.xlabel('Number') plt.ylabel('Squared') plt.show() def read_csv(filename): numbers = [] squared = [] with open(filename) as f: reader = csv.reader(f) next(reader) for row in reader: numbers.append(int(row[0])) squared.append((int(row[1]))) return numbers, squared if __name__ == '__main__': numbers, squared = read_csv('numbers.csv') scatter_plot(numbers, squared)


read csv()函数使用csv模块(在程序开始时导入)中定义的reader()函数读取CSV文件(可以理解为使用csv方式打开),调用该函数,将文件对象f作为参数传递它。然后,该函数返回一个指向CSV文件第一行的指针(pointer)。我们知道文件的第一行是标题, 我们要跳过,所以我们使用next()函 数将指针移动到下一行。然后,使用for循环读取文件的每一行,每一行由标签row 指代,row[0]指代数据的第一列, row[1]指代第二列。对于这个特定的文件,我们知道这两个数字都是整数,所以我们使用int()函数将它们的类型从字符串转换为整数,并将它们存储在两个列表中。返回结果是一个包含数字,另一个包含平方值的两个列表。

然后我们使用numbers和squared这两个列表作为参数来调用scatter_ plot()函数,创建散点图。我们之前写的find_corr_x_y()函数也可以很容易地用于计算两组数字之间的相关系数。

现在我们来处理一个更复杂的CSV文件。在你的浏览器中打开Google Correlate的页面,输入你想搜索的任何查询(例如,夏天),然后单击搜索相关按钮。你将看到在“与夏天相关”标题下返回了一些结果,第一个结果是相关性最高(每个结果左边的数字)。单击图形上方的“散点图”选项可查看散点图,其中x轴标记为夏天,y轴用顶部结果标记。忽略在两个轴上绘制的精确数字,因为我们只对相关性和散点图感兴趣。

在散点图上方,单击“导出数据为CSV",文件下载将开始。将此文件保存在与程序相同的目录中。

此CSV文件与我们之前看到的文件略有不同。在文件的开头,你会看到一些空行和带有#符号的行,直到最后你会看到标题和数据。这些行对我们来说是没有用的,使用能打开CSV文件的任何软件,手动删除它们,使得文件的第一行是标题。你还需要删除文件末尾的空行。然后保存文件。在这个步骤中,我们清理了文件以便能更简单地使用Python执行操作,此步骤通常称为预处理数据。

标题有几列,第一列包含每行中数据的日期(每行的数据对应于此列中日期开始的周数),第二列是你输入的搜索查询,第三列显示与你的搜索查询相关性最高的搜索查询,其他列包含与你输入的搜索查询按相关性降序排列的其他多个搜索查询。这些列中的数字是相应搜索查询的z分数。z分数表示在特定周期间搜索词语的次数与该词每周的总平均搜索次数之间的差异。正的z分数值表示搜索次数高于该周搜索次数的均值,负的z分数值表示低于均值。 现在,我们只处理第二和第三列。你可以使用read_csv()函数来读取这些列,只需修改上述代码中的read_csv()函数,并且修改也很简单,读取第二列和第三列,并且将其转为浮点数即可。


def read_csv(filename): summer = [] highest_correlated = [] with open(filename) as f: reader = csv.reader(f) next(reader) for row in reader: print(row) summer.append(float(row[1])) highest_correlated.append((float(row[2]))) return summer, highest_correlated


然后加入到刚刚程序中,即可绘制出你输入和搜索和与其相关性最高的搜索的散点图:

python中数学统计方法(Python数学编程第三章)(4)

Summer与Highest_correlataed的散点图

,