当前位置: 首页 > 科技观察

使用Python和GNUOctave绘制数据

时间:2023-03-14 00:38:13 科技观察

了解如何使用Python和GNUOctave完成常见的数据科学任务。数据科学是一个跨越编程语言的知识领域。有些语言以解决该领域的问题而闻名,而另一些则鲜为人知。这篇文章将帮助您熟悉一些流行语言的数据科学。选择Python和GNUOctave进行数据科学工作我经常尝试学习一种新的编程语言。为什么?既有对旧方式的厌倦,也有对新方式的好奇。当我开始学习编程时,我唯一会的语言是C。那几年的编程是艰难而危险的,因为我必须手动分配内存,管理指针,并记得释放内存。然后一个朋友建议我试试Python,现在我的编程生活轻松多了。虽然程序运行慢了很多,但我不用再为写分析软件而吃亏了。但是,我很快意识到每种语言都有其比其他语言更好的应用场景。然后我学习了其他一些语言,每种语言都给我带来了新的东西。发现新的编程风格使我能够将一些解决方案移植到其他语言,这让一切都变得更加有趣。为了感受一种新的编程语言(及其文档),我总是从编写一些执行我熟悉的任务的示例程序开始。为此,我将解释如何使用Python和GNUOctave编写程序来完成您可以归类为数据科学的特定任务。如果您已经熟悉其中一种语言,请从它开始,然后通过其他语言寻找相同点和不同点。这篇文章并不是编程语言的详尽比较,只是一个小的展示。所有程序都应在命令行上运行,而不是使用图形用户界面(GUI)。可以在polyglot_fit存储库中找到完整的示例。编程任务您将在本系列中编写的程序:从CSV文件中读取数据用直线插值数据(例如f(x)=m?x+q)生成结果的图像文件这是许多人遇到的常见问题数据科学家条件。示例数据是Anscombe的四重奏的第一组,如下表所示。这是一个人为构建的数据集,用直线拟合时给出相同的结果,但它们的曲线却有很大不同。数据文件是一个文本文件,以制表符作为列分隔符,前几行作为标题。此任务将仅使用第一组(即前两列)。PythonWayPython是一种通用编程语言,也是当今最流行的语言之一(根据TIOBE指数、RedMonk编程语言排名、编程语言流行度指数、GitHubOctoverseState和其他来源的调查结果)。它是一种解释性语言;因此,源代码由执行指令的程序读取和评估。它有一个全面的标准库,通常非常好用(我没有证明最后一句话;这只是我的愚见)。安装要使用Python进行开发,您需要一个解释器和一些库。最低要求是:用于轻松操作数组和矩阵的NumPy用于数据科学的SciPy用于绘图的Matplotlib在Fedora上安装它们很容易:sudodnfinstallpython3python3-numpypython3-scipypython3-matplotlibPython中的代码注释,注释通过添加实现a#在行的开头,该行的其余部分将被解释器丢弃:#Thisisacommentignoredbytheinterpreter.fitting_python.py示例使用注释在源代码中插入许可证信息。第一行是一个特殊注释,允许在命令行执行脚本:#!/usr/bin/envpython3这一行告诉命令行解释器,该脚本需要由程序python3执行。必需的库在Python中,库和模块可以作为对象导入(如示例中的第一行),其中包含库的所有函数和成员。它们可以使用自定义标签重命名为:importnumpyasnpfromscipyimportstatsimportmatplotlib.pyplotasplt您也可以决定只导入一个子模块(如第二行和第三行)。有两种(本质上)等效的语法:importmodule.submodule和frommoduleimportsubmodule。定义变量Python变量在第一次赋值时声明:input_file_name="anscombe.csv"delimiter="\t"skip_header=3column_x=0column_y=1变量类型是从分配给变量的值推断的。除非在模块中声明并且只能读取,否则没有常量值的变量。按照惯例,不应修改的变量应以大写字母命名。打印输出通过命令行运行程序意味着输出只打印在终端上。Python有print()函数,它默认打印它的参数并在输出的末尾附加一个换行符:print("####Anscombe'sfirstsetwithPython####")在Python中,你可以结合print()函数,具有字符串类的格式化功能。字符串有一个格式化方法,可用于将一些格式化文本添加到字符串本身。例如,可以添加格式化浮点数,例如:print("Slope:{:f}".format(slope))=np.genfromtxt(input_file_name,delimiter=delimiter,skip_header=skip_header)在Python中,函数可以有可变数量的参数,您可以通过指定所需参数来传递参数的子集。数组是非常强大的类似矩阵的对象,可以很容易地拆分成更小的数组:x=data[:,column_x]y=data[:,column_y]冒号选择整个范围,也可以用来选择子范围。例如,要选择数组的前两行,可以使用:first_two_rows=data[0:1,:]拟合数据SciPy提供了方便的数据拟合函数,例如linregress()函数。这个函数提供了一些与拟合相关的重要值,比如两个数据集的斜率、截距、相关系数:slope,intercept,r_value,p_value,std_err=stats.linregress(x,y)print("斜率:{:f}".format(slope))print("截距:{:f}".format(截距))print("相关系数:{:f}".format(r_value))因为linregress()提供了几条信息,所以结果可以同时保存到几个变量中。绘图Matplotlib库仅绘制数据点,因此您应该定义要绘制的点的坐标。x和y数组已定义,因此您可以直接绘制它们,但您还需要数据点来表示直线。fit_x=np.linspace(x.min()-1,x.max()+1,100)linspace()函数方便生成一组两个值之间等间距的值。利用强大的NumPy数组可以轻松计算纵坐标,可以像普通数值变量一样在公式中使用:fit_y=slope*fit_x+intercept该公式在数组中按元素应用;因此,结果在初始数组条目中具有相同的数量。绘制,首先,定义一个包含所有图形的图形对象:fig_width=7#inchfig_height=fig_width/16*9#inchfig_dpi=100fig=plt.figure(figsize=(fig_width,fig_height),dpi=fig_dpi)一个图形可以是画了几个地块;在Matplotlib中,这些图称为轴。此示例定义了一个单轴对象来绘制数据点:ax=fig.add_subplot(111)ax.plot(fit_x,fit_y,label="Fit",linestyle='-')ax.plot(x,y,label="数据",标记='.',linestyle='')ax.legend()ax.set_xlim(min(x)-1,max(x)+1)ax.set_ylim(min(y)-1,max(y)+1)ax.set_xlabel('x')ax.set_ylabel('y')将图形保存到PNG图形文件中:fig.savefig('fit_python.png')如果要显示(而不是ofsave)theplot,call:plt.show()此示例引用了绘图部分中使用的所有对象:它定义了对象fig和对象ax。这在技术上是不必要的,因为可以直接使用plt对象来绘制数据集。《Matplotlib 教程》显示了这样一个界面:plt.plot(fit_x,fit_y)坦率地说,我不喜欢这种方法,因为它隐藏了各种对象之间发生的重要交互。不幸的是,有时官方示例有点混乱,因为它们倾向于使用不同的方法。在这个简单的示例中,引用图形对象是不必要的,但在更复杂的示例中(例如在GUI中嵌入图形时),引用图形对象变得很重要。结果命令行输入:####Anscombe用Python的第一个集合####Slope:0.500091Intercept:3.000091Correlationcoefficient:0.816421ThisistheimagegeneratedbyMatplotlib:PlotandfitofthedatasetobtainedwithPythonGNUOctavewayGNUOctavelanguage主要用于数值计算。它提供了一种用于操作向量和矩阵的简单语法,并具有一些强大的绘图工具。它是一种类似于Python的解释型语言。由于Octave的语法几乎与MATLAB兼容,因此它通常被描述为MATLAB的免费替代品。Octave没有被列为最流行的编程语言,而MATLAB是,所以Octave在某种意义上相当流行。MATLAB早于NumPy,我认为它受到了它的启发。当您查看此示例时,您会发现相似之处。安装fitting_octave.m示例只需要基本的Octave包。在Fedora中安装相当简单:sudodnfinstalloctave代码注释在Octave中,您可以使用百分号(%)为代码添加注释。如果不需要与MATLAB兼容,也可以使用#。使用#的选项允许您像Python示例一样编写特殊的注释行,以直接在命令行上执行脚本。必要的库本示例中使用的所有内容都包含在基础包中,因此您无需加载任何新的库。如果你需要一个库,语法是pkgloadmodule。此命令将模块的功能添加到可用功能列表中。在这方面,Python具有更大的灵活性。定义变量定义变量的语法与Python基本相同:input_file_name="anscombe.csv";不需要,但它会抑制行结果的输出。如果没有分号,解释器将打印表达式的结果:octave:1>input_file_name="anscombe.csv"input_file_name=anscombe.csvoctave:2>sqrt(2)ans=1.4142强大的函数printf()是为了在终端打印。与Python不同,printf()函数不会自动在打印字符串的末尾添加换行符,因此您必须添加它。第一个参数是一个字符串,它可以包含要传递给函数的其他参数的格式信息,例如:printf("Slope:%f\n",slope);在Python中,格式化内置于字符串本身,但在Octave中,它特定于printf()函数。读取数据dlmread()函数可以读取类似于CSV文件的文本内容:data=dlmread(input_file_name,delimiter,skip_header,0);结果是一个矩阵对象,它是Octave中的基本数据类型之一。可以使用类似Python的语法对矩阵进行切片:x=data(:,column_x);y=数据(:,column_y);根本区别在于索引从1而不是0开始。因此,在此示例中,列x是第一列。拟合数据要用直线拟合数据,请使用polyfit()函数。它用多项式拟合输入数据,因此您只需要使用一阶多项式:p=polyfit(x,y,1);斜率=p(1);截距=p(2);结果是具有多项式系数的矩阵;所以它选择前两个索引。要确定相关系数,请使用corr()函数:r_value=corr(x,y);最后使用printf()函数打印结果:printf("Slope:%f\n",slope);printf("Intercept:%f\n",intercept);printf("Correlationcoefficient:%f\n",r_value);绘图与Matplotlib示例相同,首先需要创建一个表示拟合线的数据集:fit_x=linspace(min(x)-1,max(x)+1,100);fit_y=斜率*fit_x+截距;与NumPy的相似性也很明显,因为它使用linspace()函数,其行为类似于Python等价物。同样,与Matplotlib一样,首先创建一个图形对象,然后创建一个轴对象来保存图形:fig_width=7;%inchfig_height=fig_width/16*9;%inchfig_dpi=100;fig=figure("units","inches","position",[1,1,fig_width,fig_height]);ax=axes("parent",fig);set(ax,"字体大小",14);set(ax,"线宽",2);要设置坐标区对象的属性,请使用set()函数。但是,该接口相当混乱,因为该函数需要一个以逗号分隔的属性和值对列表。这些对只是表示属性名称的字符串和表示属性值的第二个对象的延续。还有其他设置各种属性的函数:xlim(ax,[min(x)-1,max(x)+1]);ylim(ax,[min(y)-1,max(y)+1]);xlabel(ax,'x');ylabel(ax,'y');绘图是使用plot()函数完成的。默认行为是在每次调用时重置轴,因此需要使用函数hold()。保持(ax,“on”);绘图(ax,fit_x,fit_y,“标记”,“无”,“线型”,“-”,“线宽”,2);绘图(ax,x,y,“标记",".","markersize",20,"linestyle","none");hold(ax,"off");此外,可以在plot()函数中添加属性和值对。图例必须单独创建,标签应手动声明:lg=legend(ax,"Fit","Data");set(lg,"location","northwest");最后,将输出保存为PNG图像:image_size=sprintf("-S%f,%f",fig_width*fig_dpi,fig_height*fig_dpi);image_resolution=sprintf("-r%f,%f",fig_dpi);打印(图,'fit_octave.png','-dpng',image_size,image_resolution);令人困惑的是,在这种情况下,选项作为字符串传递,带有属性名称和值。由于Octave字符串中没有Python格式化工具,因此必须使用sprintf()函数。它的行为类似于printf()函数,但它不是打印结果,而是将其作为字符串返回。在这个例子中,就像在Python中一样,图形对象被清楚地引用以保持它们之间的交互。如果Python关于此的文档有点令人困惑,那么Octave的文档就更糟了。我发现的大多数例子都不关心引用对象;相反,它们依赖于作用于当前活动绘图的绘图命令。全局根图形对象跟踪现有图形和轴。命令行上的结果输出是:####Anscombe'sfirstsetwithOctave####Slope:0.500091Intercept:3.000091Correlationcoefficient:0.816421它显示了使用Octave生成??的结果图像。使用Octave获得的数据集的绘图和拟合遵循Python和GNUOctave可以绘制相同的信息,尽管它们以不同的方式进行。如果你想探索其他语言来完成类似的任务,我强烈建议你看看RosettaCode。这是一个了不起的资源,可以了解如何用多种语言解决同一个问题。