使用 Python 和 GNU Octave 繪製數據 | Linux 中國

2021-03-02 Linux中國

數據科學是跨越程式語言的知識領域。有些語言以解決這一領域的問題而聞名,而另一些則鮮為人知。這篇文章將幫助你熟悉用一些流行的語言完成數據科學的工作。

選擇 Python 和 GNU Octave 做數據科學工作

我經常嘗試學習一種新的程式語言。為什麼?這既有對舊方式的厭倦,也有對新方式的好奇。當我開始學習編程時,我唯一知道的語言是 C 語言。那些年的編程生涯既艱難又危險,因為我必須手動分配內存、管理指針、並記得釋放內存。

後來一個朋友建議我試試 Python,現在我的編程生活變得輕鬆多了。雖然程序運行變得慢多了,但我不必通過編寫分析軟體來受苦了。然而,我很快就意識到每種語言都有比其它語言更適合自己的應用場景。後來我學習了一些其它語言,每種語言都給我帶來了一些新的啟發。發現新的編程風格讓我可以將一些解決方案移植到其他語言中,這樣一切都變得有趣多了。

為了對一種新的程式語言(及其文檔)有所了解,我總是從編寫一些執行我熟悉的任務的示例程序開始。為此,我將解釋如何用 Python 和 GNU Octave 編寫一個程序來完成一個你可以歸類為數據科學的特殊任務。如果你已經熟悉其中一種語言,從它開始,然後通過其他語言尋找相似之處和不同之處。這篇文章並不是對程式語言的詳盡比較,只是一個小小的展示。

所有的程序都應該在命令行上運行,而不是用圖形用戶界面(GUI)。完整的例子可以在 polyglot_fit 存儲庫中找到。

編程任務

你將在本系列中編寫的程序:

◈ 用直線插入數據(例如 f(x)=m ⋅ x + q)

這是許多數據科學家遇到的常見情況。示例數據是 Anscombe 的四重奏的第一組,如下表所示。這是一組人工構建的數據,當用直線擬合時會給出相同的結果,但是它們的曲線非常不同。數據文件是一個文本文件,以制表符作為列分隔符,開頭幾行作為標題。此任務將僅使用第一組(即前兩列)。

Python 方式

Python 是一種通用程式語言,是當今最流行的語言之一(依據 TIOBE 指數、RedMonk 程式語言排名、程式語言流行指數、GitHub Octoverse 狀態和其他來源的調查結果)。它是一種解釋型語言;因此,原始碼由執行該指令的程序讀取和評估。它有一個全面的標準庫並且總體上非常好用(我對這最後一句話沒有證據;這只是我的拙見)。

安裝

要使用 Python 開發,你需要解釋器和一些庫。最低要求是:

在 Fedora 安裝它們是很容易的:

sudo dnf install python3 python3-numpy python3-scipy python3-matplotlib

代碼注釋

在 Python中,注釋是通過在行首添加一個 # 來實現的,該行的其餘部分將被解釋器丟棄:

fitting_python.py 示例使用注釋在原始碼中插入許可證信息,第一行是特殊注釋,它允許該腳本在命令行上執行:

這一行通知命令行解釋器,該腳本需要由程序 python3 執行。

需要的庫

在 Python 中,庫和模塊可以作為一個對象導入(如示例中的第一行),其中包含庫的所有函數和成員。可以通過使用 as 方式用自定義標籤重命名它們:

import matplotlib.pyplot as plt

你也可以決定只導入一個子模塊(如第二行和第三行)。語法有兩個(基本上)等效的方式:import module.submodule 和 from module import submodule。

定義變量

Python 的變量是在第一次賦值時被聲明的:

input_file_name = "anscombe.csv"

變量類型由分配給變量的值推斷。沒有具有常量值的變量,除非它們在模塊中聲明並且只能被讀取。習慣上,不應被修改的變量應該用大寫字母命名。

列印輸出

通過命令行運行程序意味著輸出只能列印在終端上。Python 有 print() 函數,默認情況下,該函數列印其參數,並在輸出的末尾添加一個換行符:

print("#### Anscombe's first set with Python ####")

在 Python 中,可以將 print() 函數與字符串類的格式化能力相結合。字符串具有format 方法,可用於向字符串本身添加一些格式化文本。例如,可以添加格式化的浮點數,例如:

print("Slope: {:f}".format(slope))

讀取數據

使用 NumPy 和函數 genfromtxt() 讀取 CSV 文件非常容易,該函數生成 NumPy 數組:

data = np.genfromtxt(input_file_name, delimiter = delimiter, skip_header = skip_header)

在 Python 中,一個函數可以有數量可變的參數,你可以通過指定所需的參數來傳遞一個參數的子集。數組是非常強大的矩陣狀對象,可以很容易地分割成更小的數組:

冒號選擇整個範圍,也可以用來選擇子範圍。例如,要選擇數組的前兩行,可以使用:

first_two_rows = data[0:1, :]

擬合數據

SciPy 提供了方便的數據擬合功能,例如 linregress() 功能。該函數提供了一些與擬合相關的重要值,如斜率、截距和兩個數據集的相關係數:

slope, intercept, r_value, p_value, std_err = stats.linregress(x, y)print("Slope: {:f}".format(slope))print("Intercept: {:f}".format(intercept))print("Correlation coefficient: {: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_height = fig_width / 16 * 9 #inchfig = 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 = "Data", marker = '.', linestyle = '')ax.set_xlim(min(x) - 1, max(x) + 1)ax.set_ylim(min(y) - 1, max(y) + 1)

將該圖保存到 PNG 圖形文件中,有:

fig.savefig('fit_python.png')

如果要顯示(而不是保存)該繪圖,請調用:

此示例引用了繪圖部分中使用的所有對象:它定義了對象 fig 和對象 ax。這在技術上是不必要的,因為 plt 對象可以直接用於繪製數據集。《Matplotlib 教程》展示了這樣一個接口:

坦率地說,我不喜歡這種方法,因為它隱藏了各種對象之間發生的重要交互。不幸的是,有時官方的例子有點令人困惑,因為他們傾向於使用不同的方法。在這個簡單的例子中,引用圖形對象是不必要的,但是在更複雜的例子中(例如在圖形用戶界面中嵌入圖形時),引用圖形對象就變得很重要了。

結果

命令行輸入:

#### Anscombe's first set with Python ####Correlation coefficient: 0.816421

這是 Matplotlib 產生的圖像:

Plot and fit of the dataset obtained with Python

GNU Octave 方式

GNU Octave 語言主要用於數值計算。它提供了一個簡單的操作向量和矩陣的語法,並且有一些強大的繪圖工具。這是一種像 Python 一樣的解釋語言。由於 Octave 的語法幾乎兼容 MATLAB,它經常被描述為一個替代 MATLAB 的免費方案。Octave 沒有被列為最流行的程式語言,而 MATLAB 則是,所以 Octave 在某種意義上是相當流行的。MATLAB 早於 NumPy,我覺得它是受到了前者的啟發。當你看這個例子時,你會看到相似之處。

安裝

fitting_octave.m 的例子只需要基本的 Octave 包,在 Fedora 中安裝相當簡單:

代碼注釋

在 Octave 中,你可以用百分比符號(%)為代碼添加注釋,如果不需要與 MATLAB 兼容,你也可以使用 #。使用 # 的選項允許你編寫像 Python 示例一樣的特殊注釋行,以便直接在命令行上執行腳本。

必要的庫

本例中使用的所有內容都包含在基本包中,因此你不需要加載任何新的庫。如果你需要一個庫,語法是 pkg load module。該命令將模塊的功能添加到可用功能列表中。在這方面,Python 具有更大的靈活性。

定義變量

變量的定義與 Python 的語法基本相同:

input_file_name = "anscombe.csv";

請注意,行尾有一個分號;這不是必需的,但是它會抑制該行結果的輸出。如果沒有分號,解釋器將列印表達式的結果:

octave:1> input_file_name = "anscombe.csv"input_file_name = anscombe.csv

列印輸出結果

強大的函數 printf() 是用來在終端上列印的。與 Python 不同,printf() 函數不會自動在列印字符串的末尾添加換行,因此你必須添加它。第一個參數是一個字符串,可以包含要傳遞給函數的其他參數的格式信息,例如:

printf("Slope: %f\n", slope);

在 Python 中,格式是內置在字符串本身中的,但是在 Octave 中,它是特定於 printf() 函數。

讀取數據

dlmread() 函數可以讀取類似 CSV 文件的文本內容:

data = dlmread(input_file_name, delimiter, skip_header, 0);

結果是一個矩陣對象,這是 Octave 中的基本數據類型之一。矩陣可以用類似於 Python 的語法進行切片:

根本的區別是索引從 1 開始,而不是從 0 開始。因此,在該示例中,x 列是第一列。

擬合數據

要用直線擬合數據,可以使用 polyfit() 函數。它用一個多項式擬合輸入數據,所以你只需要使用一階多項式:

結果是具有多項式係數的矩陣;因此,它選擇前兩個索引。要確定相關係數,請使用 corr() 函數:

最後,使用 printf() 函數列印結果:

printf("Slope: %f\n", slope);printf("Intercept: %f\n", intercept);printf("Correlation coefficient: %f\n", r_value);

繪圖

與 Matplotlib 示例一樣,首先需要創建一個表示擬合直線的數據集:

fit_x = linspace(min(x) - 1, max(x) + 1, 100);fit_y = slope * fit_x + intercept;

與 NumPy 的相似性也很明顯,因為它使用了 linspace() 函數,其行為就像 Python 的等效版本一樣。

同樣,與 Matplotlib 一樣,首先創建一個圖對象,然後創建一個軸對象來保存這些圖:

fig_height = fig_width / 16 * 9; %inchfig = figure("units", "inches",             "position", [1, 1, fig_width, fig_height]);ax = axes("parent", fig);

要設置軸對象的屬性,請使用 set() 函數。然而,該接口相當混亂,因為該函數需要一個逗號分隔的屬性和值對列表。這些對只是代表屬性名的一個字符串和代表該屬性值的第二個對象的連續。還有其他設置各種屬性的函數:

xlim(ax, [min(x) - 1, max(x) + 1]);ylim(ax, [min(y) - 1, max(y) + 1]);

繪圖是用 plot() 功能實現的。默認行為是每次調用都會重置坐標軸,因此需要使用函數 hold()。

此外,還可以在 plot() 函數中添加屬性和值對。legend 必須單獨創建,標籤應手動聲明:

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);print(fig, 'fit_octave.png',

令人困惑的是,在這種情況下,選項被作為一個字符串傳遞,帶有屬性名和值。因為在 Octave 字符串中沒有 Python 的格式化工具,所以必須使用 sprintf() 函數。它的行為就像 printf() 函數,但是它的結果不是列印出來的,而是作為字符串返回的。

在這個例子中,就像在 Python 中一樣,圖形對象很明顯被引用以保持它們之間的交互。如果說 Python 在這方面的文檔有點混亂,那麼 Octave 的文檔就更糟糕了。我發現的大多數例子都不關心引用對象;相反,它們依賴於繪圖命令作用於當前活動圖形。全局根圖形對象跟蹤現有的圖形和軸。

結果

命令行上的結果輸出是:

#### Anscombe's first set with Octave ####Correlation coefficient: 0.816421

它顯示了用 Octave 生成的結果圖像。

Plot and fit of the dataset obtained with Octave

接下來

Python 和 GNU Octave 都可以繪製出相同的信息,儘管它們的實現方式不同。如果你想探索其他語言來完成類似的任務,我強烈建議你看看 Rosetta Code。這是一個了不起的資源,可以看到如何用多種語言解決同樣的問題。

你喜歡用什麼語言繪製數據?在評論中分享你的想法。

via: https://opensource.com/article/20/2/python-gnu-octave-data-science

作者:Cristiano L. Fontana 選題:lujun9972 譯者:heguangzhi 校對:wxy

本文由 LCTT 原創編譯,Linux中國 榮譽推出

相關焦點

  • 飛凌課堂丨開發板Python 移植教程
    >configure --host=arm-cortex_a9-linux-gnueabi \--prefix=$PWD/../Python-2.7.13/configure --prefix=`pwd` \--host=arm-cortex_a9-linux-gnueabi \--build=x86_64-linux-gnu \--enable-ipv6 \--enable-static
  • Python中使用matplotlib繪製灰度直方圖
    灰度直方圖在數據統計分析、圖像處理中有著比較廣泛的應用,下面就介紹一下如何在Python中使用matplotlib來繪製灰度直方圖。
  • 迅為iTOP-iMX6ULL 開發板-Python 移植
    92.1 源碼包和文檔在一起的源碼包有:「python-2.7.3 源碼和補丁.zip」---python 壓縮包和補丁文件;「install_python.tar」---編譯好的 sqlite 庫文件;
  • 各種姿勢的debug(從python一路debug到C++)
    本文緊接上篇讓VScode和大型IDE一樣牛逼?利用VScode和Cmake編譯插件構建C++工程,建議看完上篇再看本篇~VSCode是真正的生產力工具,尤其是前一陣子推出的remote-SSH功能。什麼是remote-SSH,這裡簡單介紹下。
  • 使用Python和R繪製數據地圖的十七個經典案例
    在這篇博客中,我將一些優秀的用戶內核變成迷你教程,作為在Kaggle上發布的數據集進行繪製地圖的開始。這篇文章中,你將學習如何用Python和R,使用包括實際代碼示例的幾種方法來布局和可視化地理空間數據。我還列出了資源,以便你可以了解每個教程中突出顯示的每個包以及進一步的用戶分析,從而獲得更多的靈感。 前言 為了探索目的而創建一個簡單的地圖不再需要你學習如何操作shapefile或想像投影。並且,無論你喜歡在R或Python,都有快速和簡單的方法把你的數據展現在地圖上。
  • 用 Python 繪製數據的7種最流行的方法 | Linux 中國
    比較七個在 Python 中繪圖的庫和 API,看看哪個最能滿足你的需求。「如何在 Python 中繪圖?」曾經這個問題有一個簡單的答案:Matplotlib 是唯一的辦法。如今,Python 作為數據科學的語言,有著更多的選擇。你應該用什麼呢?本指南將幫助你決定。
  • 嵌入式ARM-Linux平臺上的編譯、配置和運行使用
    本文介紹了嵌入式ARM-Linux上的常用應用程式wpa_supplicant(以及wpa_supplicant依賴的libnl和openssl)的編譯、配置和運行使用,iw、hostapd等應用的編譯和使用
  • PHP、Python 和 Ruby 語言的區別
    2、PHP vs Python vs Ruby: 主流網站使用情況Winner – 平局8、PHP vs Python vs Ruby:工作崗位和薪水Winner – PHP原文來自:  http://www.linuxeden.com/a/239本文地址:  http://www.linuxprobe.com/php-python-ruby.html編輯:馮振華,審核員:逄增寶
  • GNU 核心實用程序簡介 | Linux 中國
    許多 Linux 系統管理員最基本和常用的工具主要包括在兩套實用程序中:GNU 核心實用程序(coreutils)和 util-linux。它們的基本功能允許系統管理員執行許多管理 Linux 系統的任務,包括管理和操作文本文件、目錄、數據流、存儲介質、進程控制、文件系統等等。
  • linux pwn入門學習到放棄
    此技術需要作業系統和軟體相配合。ASLR在linux中使用此技術後,殺死某程序後重新開啟,地址就會會改變。1 - 表示將mmap的基址,stack和vdso頁面隨機化。2 - 表示在1的基礎上增加棧(heap)的隨機化。可以防範基於Ret2libc方式的針對DEP的攻擊。ASLR和DEP配合使用,能有效阻止攻擊者在堆棧上運行惡意代碼。
  • Linux DNS 查詢剖析(第一部分) | Linux 中國
    root@linuxdns1:~# host bbc.co.uk | head -1bbc.co.uk has address 151.101.192.81對於同一個域名,兩個程序得到的 IP 地址是相同的;那麼它們是使用同樣的方法得到結果的吧?事實並非如此。
  • 利用Anaconda在Windows及Linux下搭建Python環境【手把手版】
    ❞一、同系列文章本文是Python數據分析基礎系列文章的第20篇❝python3基礎01數值和字符串(一)python3基礎02數值和字符串(二)python3基礎03列表(list)和元組(tuple)python3基礎04字典(dict)和集合(set)python3基礎
  • 一次搞定 Arm Linux 交叉編譯
    為了讓這個流程變得簡單,開發者們為不同的晶片開發了不同的編譯器,比如針對 Arm 平臺的 arm-linux-gcc,針對 mips 平臺的 mips-linux-gnu-gcc,這些編譯器都是基於 GCC 針對具體的架構指令集進行對應配置,所以它們在運行的時候就就會生成和該目標平臺對應的可執行文件。
  • Linux 平臺下 Python 腳本編程入門(一)
    Linux 中的 PythonPython 2.x 和 3.x 通常已經內置在現代 Linux 發行版中,你可以立刻使用它。你可以終端模擬器中輸入 python 或python3 來進入 Python shell, 並輸入 quit() 退出。
  • Python學習第93課-導入csv數據並繪製折線圖
    【每天幾分鐘,從零入門python編程的世界!】之前我們畫各種圖,都是把需要分析的數據,手寫輸入Python的開發工具中去的,這樣做是為了學習和理解Python數據可視化畫圖的原理,但是在實際工作中,我們一定是去處理Python開發工具之外的一些數據,比如Excel表格保存的數據,或者其他格式的文件保存的數據。
  • 【Python教程】用Python進行數據可視化
    在本文中,我將介紹如何開始使用Python和matplotlib、seaborn兩個庫對數據進行可視化。通過上面的例子,我們應該可以感受到利用可視化能多麼美麗的展示數據。而且和其它語言相比,使用 Python 進行可視化更容易簡便一些。
  • python之字符串詳解
    學習過C/C++的同學轉寫python會很容易理解裡面的規則,從而使得代碼更加高效,優雅。下面我們總結一下python的基礎知識。C/C++標識符的命名規則:變量名只能包含字母、數字和下劃線,並且不可以以數字打頭。不可以使用C/C++的關鍵字和函數名作為變量名。
  • 為什麼入門大數據選擇Python而不是Java?
    Python具有豐富和強大的庫。它常被暱稱為膠水語言,能夠把用其他語言製作的各種模塊(尤其是C/C++)很輕鬆地聯結在一起。7月20日,IEEE發布2017年程式語言排行榜:Python高居首位。java和python,都可以運行於linux作業系統,但很多linux可以原生支持python,java需要自行安裝。
  • 使用Python和Jupyter Notebook進行數據分析
    懷揣著學習和進取的心態,我立刻在google上面檢索關鍵詞:python jupyter notebook data analysis,閱讀了一些與這個主題相關的系列文章,並且積極地進行實踐之,讓自己一來熟悉jupyter notebook這個工具,二來藉助這個工具實現更有效地做數據分析。