Merge pull request #17597 from wxy/20200224-Using-C-and-C---for-data-science

PRF&PUB:20200224 Using C and C   for data science
This commit is contained in:
Xingyu.Wang 2020-03-02 10:26:50 +08:00 committed by GitHub
commit f4ab7156c2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,8 +1,8 @@
[#]: collector: (lujun9972)
[#]: translator: (wxy)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-11950-1.html)
[#]: subject: (Using C and C++ for data science)
[#]: via: (https://opensource.com/article/20/2/c-data-science)
[#]: author: (Cristiano L. Fontana https://opensource.com/users/cristianofontana)
@ -10,30 +10,29 @@
在数据科学中使用 C 和 C++
======
> 让我们使用 C99 和 C++ 11 完成常见的数据科学任务。
> 让我们使用 C99 和 C++11 完成常见的数据科学任务。
![metrics and data shown on a computer screen][1]
虽然 [Python][2] 和 [R][3] 之类的语言在数据科学中越来越受欢迎,但是 C 和 C++ 对于高效的数据科学来说是一个不错的选择。在本文中,我们将使用 [C99][4] 和 [C++11][5] 编写一个程序,该程序使用 [Anscombe 的四重奏][6]数据集,下面将对其进行解释。
我在一篇涉及 [Python 和 GNU Octave][7] 的文章中写了我不断学习语言的动机,值得大家回顾。所有程序都应在[命令行][8]上运行,而不是在[图形用户界面GUI][9]上运行。完整的示例可在 [polyglot_fit 存储库][10]中找到。
我在一篇涉及 [Python 和 GNU Octave][7] 的文章中写了我不断学习编程语言的动机,值得大家回顾。这里所有的程序都需要在[命令行][8]上运行,而不是在[图形用户界面GUI][9]上运行。完整的示例可在 [polyglot_fit 存储库][10]中找到。
### 编程任务
你将在本系列中编写的程序:
* 从 [CSV 文件] [11]中读取数据
* 从 [CSV 文件][11]中读取数据
* 用直线插值数据(即 `f(x)=m ⋅ x + q`
* 将结果绘制到图像文件
这是许多数据科学家遇到的普遍情况。示例数据是 [Anscombe 的四重奏] [6]的第一组,如下表所示。这是一组人工构建的数据,当拟合直线时可以提供相同的结果,但是它们的曲线非常不同。数据文件是一个文本文件,其中的制表符用作列分隔符,几行作为标题。该任务将仅使用第一组(即前两列)。
[Anscombe 的四重奏][6]
这是许多数据科学家遇到的普遍情况。示例数据是 [Anscombe 的四重奏][6]的第一组,如下表所示。这是一组人工构建的数据,当拟合直线时可以提供相同的结果,但是它们的曲线非常不同。数据文件是一个文本文件,其中的制表符用作列分隔符,前几行作为标题。该任务将仅使用第一组(即前两列)。
![](https://img.linux.net.cn/data/attachment/album/202002/29/122805h3yrs1dkrgysssxk.png)
### C 语言的方式
[C][12] 语言是通用编程语言,是当今使用最广泛的语言之一(依据 [TIOBE 榜单][13]、[RedMonk 编程语言排名][14]、[编程语言流行度榜单][15]和 [GitHub Octoverse 状态][16])。这是一种相当古老的语言(大约诞生在 1973 年),并且用它编写了许多成功的程序(例如 Linux 内核和 Git 仅是其中两个例子)。它也是最接近计算机内部运行的语言之一,因为它直接用于操作内存。它是一种[编译语言] [17];因此,源代码必须由[编译器][18]转换为[机器代码][19]。它的[标准库][20]很小,功能也不多,因此开发了其他库来提供缺少的功能。
[C][12] 语言是通用编程语言,是当今使用最广泛的语言之一(依据 [TIOBE 指数][13]、[RedMonk 编程语言排名][14]、[编程语言流行度指数][15]和 [GitHub Octoverse 状态][16] 得来)。这是一种相当古老的语言(大约诞生在 1973 年),并且用它编写了许多成功的程序(例如 Linux 内核和 Git 仅是其中两个例子)。它也是最接近计算机内部运行机制的语言之一,因为它直接用于操作内存。它是一种[编译语言][17];因此,源代码必须由[编译器][18]转换为[机器代码][19]。它的[标准库][20]很小,功能也不多,因此人们开发了其它库来提供缺少的功能。
我最常在[数字运算][21]中使用该语言,主要是因为其性能。我觉得使用起来很繁琐,因为它需要很多[样板代码][22]但是它在各种环境中都得到了很好的支持。C99 标准是最新版本,增加了一些漂亮的功能,并且得到了编译器的良好支持。
@ -41,7 +40,7 @@
#### 安装
要使用 C99 进行开发,你需要一个编译器。我通常使用 [Clang][23],不过 [GCC][24] 是另一个有效的开源编译器。对于线性拟合,我选择使用 [GNU 科学库] [25]。对于绘图,我找不到任何明智的库,因此该程序依赖于外部程序:[Gnuplot] [26]。该示例还使用动态数据结构来存储数据,该结构在[伯克利软件分发版BSD][27]中定义。
要使用 C99 进行开发,你需要一个编译器。我通常使用 [Clang][23],不过 [GCC][24] 是另一个有效的开源编译器。对于线性拟合,我选择使用 [GNU 科学库][25]。对于绘图,我找不到任何明智的库,因此该程序依赖于外部程序:[Gnuplot][26]。该示例还使用动态数据结构来存储数据,该结构在[伯克利软件分发版BSD][27]中定义。
在 [Fedora][28] 中安装很容易:
@ -49,7 +48,7 @@
sudo dnf install clang gnuplot gsl gsl-devel
```
#### 注释代码
#### 代码注释
在 C99 中,[注释][29]的格式是在行的开头放置 `//`,行的其它部分将被解释器丢弃。另外,`/*` 和 `*/` 之间的任何内容也将被丢弃。
@ -65,7 +64,7 @@ sudo dnf install clang gnuplot gsl gsl-devel
* [头文件][30],其中包含函数说明
* 包含函数定义的源文件
头文件包含在源文件中,而库文件的源文件则与可执行文件[链接][31]。因此,此示例所需的头文件是:
头文件包含在源文件中,而库文件的源文件则[链接][31]到可执行文件。因此,此示例所需的头文件是:
```
// 输入/输出功能
@ -83,7 +82,7 @@ sudo dnf install clang gnuplot gsl gsl-devel
#### 主函数
在 C 语言中,程序必须位于称为主函数 [main()][32]的特殊函数内:
在 C 语言中,程序必须位于称为主函数 [main()][32] 的特殊函数内:
```
int main(void) {
@ -95,7 +94,7 @@ int main(void) {
#### 定义变量
在 C 语言中,变量必须在使用前声明,并且必须与类型关联。每当你要使用变量时,都必须决定要在其中存储哪种数据。你也可以指定是否打算将变量用作常量值,这不是必需的,但是编译器可以从此信息中受益。 来自存储库中的 [fitting_C99.c 程序] [33]
在 C 语言中,变量必须在使用前声明,并且必须与类型关联。每当你要使用变量时,都必须决定要在其中存储哪种数据。你也可以指定是否打算将变量用作常量值,这不是必需的,但是编译器可以从此信息中受益。 以下来自存储库中的 [fitting_C99.c 程序][33]
```
const char *input_file_name = "anscombe.csv";
@ -113,7 +112,7 @@ C 语言中的数组不是动态的,从某种意义上说,数组的长度必
int data_array[1024];
```
由于你通常不知道文件中有多少个数据点,因此请使用[单链列表][34]。这是一个动态数据结构可以无限增长。幸运的是BSD [提供了链表][35]。这是一个示例定义:
由于你通常不知道文件中有多少个数据点,因此请使用[单链列表][34]。这是一个动态数据结构可以无限增长。幸运的是BSD [提供了链表][35]。这是一个示例定义:
```
struct data_point {
@ -145,7 +144,7 @@ printf("Slope: %f\n", slope);
#### 读取数据
现在来到了困难的部分……有一些用 C 语言解析 CSV 文件的库,但是似乎没有一个库足够稳定或流行到可以放入到 Fedora 软件包存储库中。我没有为本教程添加依赖项,而是决定自己编写此部分。同样,讨论这些细节太啰嗦了,所以我只会解释大致的思路。为了简洁起见,将忽略源代码中的某些行,但是你可以在存储库中找到完整的示例。
现在来到了困难的部分……有一些用 C 语言解析 CSV 文件的库,但是似乎没有一个库足够稳定或流行到可以放入到 Fedora 软件包存储库中。我没有为本教程添加依赖项,而是决定自己编写此部分。同样,讨论这些细节太啰嗦了,所以我只会解释大致的思路。为了简洁起见,将忽略源代码中的某些行,但是你可以在存储库中找到完整的示例代码
首先,打开输入文件:
@ -210,7 +209,7 @@ double *x = malloc(sizeof(double) * entries_number);
double *y = malloc(sizeof(double) * entries_number);
```
然后,遍历链接列表以将相关数据保存到数组:
然后,遍历链表以将相关数据保存到数组:
```
SLIST_FOREACH(datum, &head, entries) {
@ -224,7 +223,7 @@ SLIST_FOREACH(datum, &head, entries) {
}
```
现在你已经完了链接列表,请清理它。要**总是**释放已手动分配的内存,以防止[内存泄漏][48]。内存泄漏是糟糕的、糟糕的、糟糕的(重要的话说三遍)。每次内存没有释放时,花园侏儒都会找不到自己的头:
现在你已经处理完了链表,请清理它。要**总是**释放已手动分配的内存,以防止[内存泄漏][48]。内存泄漏是糟糕的、糟糕的、糟糕的(重要的话说三遍)。每次内存没有释放时,花园侏儒都会找不到自己的头:
```
while (!SLIST_EMPTY(&head)) {
@ -278,7 +277,7 @@ plot 'fit_C99.csv' using 1:2 with lines title 'Fit', 'anscombe.csv' using 1:2 wi
clang -std=c99 -I/usr/include/ fitting_C99.c -L/usr/lib/ -L/usr/lib64/ -lgsl -lgslcblas -o fitting_C99
```
这个命令告诉编译器使用 C99 标准,读取 `fitting_C99.c` 文件,加载 `gsl``gslcblas` 库,并将结果保存到 `fitting_C99`。命令行上的结果输出为:
这个命令告诉编译器使用 C99 标准、读取 `fitting_C99.c` 文件、加载 `gsl``gslcblas` 库、并将结果保存到 `fitting_C99`。命令行上的结果输出为:
```
#### Anscombe's first set with C99 ####
@ -287,13 +286,13 @@ Intercept: 3.000091
Correlation coefficient: 0.816421
```
这是用 Gnuplot 生成的结果图像
这是用 Gnuplot 生成的结果图像
![Plot and fit of the dataset obtained with C99][52]
### C++11 方式
[C++][53] 语言是一种通用编程语言,也是当今使用的最受欢迎的语言之一。它是作为 [C 的继承人][54]创建的(诞生于 1983 年),重点是[面向对象程序设计OOP][55]。C++ 通常被视为 C 的超集,因此 C 程序应该能够使用 C++ 编译器进行编译。这并非完全正确,因为在某些极端情况下它们的行为有所不同。 根据我的经验C++ 比 C 需要更少的样板代码但是如果要进行对象开发语法会更困难。C++11 标准是最新版本,增加了一些漂亮的功能,并且或多或少得到了编译器的支持。
[C++][53] 语言是一种通用编程语言,也是当今使用的最受欢迎的语言之一。它是作为 [C 的继承人][54]创建的(诞生于 1983 年),重点是[面向对象程序设计OOP][55]。C++ 通常被视为 C 的超集,因此 C 程序应该能够使用 C++ 编译器进行编译。这并非完全正确,因为在某些极端情况下它们的行为有所不同。 根据我的经验C++ 与 C 相比需要更少的样板代码,但是如果要进行面向对象开发语法会更困难。C++11 标准是最新版本,增加了一些漂亮的功能,并且基本上得到了编译器的支持。
由于 C++ 在很大程度上与 C 兼容,因此我将仅强调两者之间的区别。我在本部分中没有涵盖的任何部分,则意味着它与 C 中的相同。
@ -309,7 +308,6 @@ sudo dnf install clang gnuplot gsl gsl-devel
库的工作方式与 C 语言相同,但是 `include` 指令略有不同:
```
#include <cstdlib>
#include <cstring>
@ -325,7 +323,7 @@ extern "C" {
}
```
由于 GSL 库是用 C 编写的,因此你必须将这种特殊性告知编译器。
由于 GSL 库是用 C 编写的,因此你必须将这个特殊情况告知编译器。
#### 定义变量
@ -429,17 +427,17 @@ Intercept: 3.00009
Correlation coefficient: 0.816421
```
这就是用 Gnuplot 生成的结果图像
这就是用 Gnuplot 生成的结果图像
![Plot and fit of the dataset obtained with C++11][58]
### 结论
本文提供了用 C99 和 C++11 编写的数据拟合和绘图任务的示例。由于 C++ 在很大程度上与 C 兼容因此本文利用了它们的相似性来编写了第二个示例。在某些方面C++ 更易于使用,因为它部分减轻了显式管理内存的负担。但是其语法更加复杂,因为它引入了为 OOP 编写类的可能性。但是,仍然可以用 C 使用 OOP 方法编写软件。由于 OOP 是一种编程风格,因此可以以任何语言使用。在 C 中有一些很好的 OOP 示例,例如 [GObject][59] 和 [Jansson][60]库。
本文提供了用 C99 和 C++11 编写的数据拟合和绘图任务的示例。由于 C++ 在很大程度上与 C 兼容因此本文利用了它们的相似性来编写了第二个示例。在某些方面C++ 更易于使用,因为它部分减轻了显式管理内存的负担。但是其语法更加复杂,因为它引入了为 OOP 编写类的可能性。但是,仍然可以用 C 使用 OOP 方法编写软件。由于 OOP 是一种编程风格,因此可以在任何语言中使用。在 C 中有一些很好的 OOP 示例,例如 [GObject][59] 和 [Jansson][60]库。
对于数字运算,我更喜欢在 C99 中进行因为它的语法更简单并且得到了广泛的支持。直到最近C++11 还没有得到广泛的支持我倾向于避免使用先前版本中的粗糙不足之处。对于更复杂的软件C++ 可能是一个不错的选择。
你是否也将 C 或 C++ 用于数据科学? 在评论中分享你的经验。
你是否也将 C 或 C++ 用于数据科学?在评论中分享你的经验。
--------------------------------------------------------------------------------
@ -448,7 +446,7 @@ via: https://opensource.com/article/20/2/c-data-science
作者:[Cristiano L. Fontana][a]
选题:[lujun9972][b]
译者:[wxy](https://github.com/wxy)
校对:[校对者ID](https://github.com/校对者ID)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
@ -460,7 +458,7 @@ via: https://opensource.com/article/20/2/c-data-science
[4]: https://en.wikipedia.org/wiki/C99
[5]: https://en.wikipedia.org/wiki/C%2B%2B11
[6]: https://en.wikipedia.org/wiki/Anscombe%27s_quartet
[7]: https://opensource.com/article/20/2/python-gnu-octave-data-science
[7]: https://linux.cn/article-11943-1.html
[8]: https://en.wikipedia.org/wiki/Command-line_interface
[9]: https://en.wikipedia.org/wiki/Graphical_user_interface
[10]: https://gitlab.com/cristiano.fontana/polyglot_fit