MK
摩柯社区 - 一个极简的技术知识社区
AI 面试

Ruby 的数据分析工具使用

2021-08-076.6k 阅读

1. Ruby 与数据分析基础

在深入探讨 Ruby 的数据分析工具之前,我们先来了解一下 Ruby 语言在数据分析场景下的一些基础特性。Ruby 是一种动态、面向对象的编程语言,它以简洁易读的语法而闻名。这使得它在处理数据分析任务时,代码编写更加直观和高效。

1.1 数据结构基础

在 Ruby 中,数组(Array)和哈希(Hash)是两种常用的数据结构,它们在数据分析中起着关键作用。

  • 数组:数组是有序的元素集合,可以包含不同类型的数据。例如,我们可以创建一个包含数字和字符串的数组:
data_array = [1, "two", 3.14]

在数据分析中,数组常用来存储一系列的数据值,比如从文件中读取的一列数据。

  • 哈希:哈希是一种键值对(key - value pairs)的数据结构,它提供了快速的查找能力。例如:
data_hash = {name: "Alice", age: 30, city: "New York"}

在数据分析场景下,哈希可以用来存储数据的属性及其对应的值,方便进行数据的索引和处理。

1.2 基本数据处理操作

Ruby 提供了丰富的方法来对数据进行处理。

  • 数组操作
    • 遍历数组:我们可以使用 each 方法遍历数组中的每个元素。例如,计算数组中所有数字的总和:
numbers = [1, 2, 3, 4, 5]
sum = 0
numbers.each do |num|
  sum += num
end
puts sum

这里,each 方法会对数组 numbers 中的每个元素执行一次代码块,将元素赋值给变量 num,然后在代码块中进行累加操作。

  • 筛选数组元素:使用 select 方法可以从数组中筛选出符合特定条件的元素。例如,筛选出数组中的偶数:
numbers = [1, 2, 3, 4, 5]
even_numbers = numbers.select do |num|
  num % 2 == 0
end
puts even_numbers

select 方法会遍历数组,将每个元素传入代码块,只有当代码块返回 true 时,该元素才会被包含在返回的新数组中。

  • 哈希操作
    • 访问哈希值:通过键来访问哈希中的值。例如:
person = {name: "Bob", age: 25}
puts person[:name]

这里通过键 :name 来获取对应的值 "Bob"

  • 遍历哈希:使用 each 方法可以遍历哈希中的每个键值对。例如:
person = {name: "Charlie", age: 35}
person.each do |key, value|
  puts "#{key}: #{value}"
end

在这个例子中,each 方法将哈希中的每个键值对依次传入代码块,分别赋值给 keyvalue 变量,然后在代码块中打印出来。

2. Ruby 数据分析工具之 Narray

Narray 是 Ruby 中一个用于处理多维数组的库,它在数据分析中对于处理矩阵和大型数据集非常有用。

2.1 安装 Narray

首先,我们需要安装 Narray 库。可以使用 RubyGems 进行安装:

gem install narray

2.2 创建 Narray 对象

  • 一维 Narray
require 'narray'
a = NArray.float([1, 2, 3, 4])
puts a

这里使用 NArray.float 方法创建了一个一维的浮点数 Narray 对象。

  • 多维 Narray:我们可以创建二维及以上的 Narray 对象。例如,创建一个 2x3 的二维 Narray:
require 'narray'
b = NArray.float([[1, 2, 3], [4, 5, 6]])
puts b

这将创建一个 2 行 3 列的二维数组。

2.3 Narray 的基本运算

  • 算术运算:Narray 支持各种算术运算,并且这些运算会应用到数组的每个元素上。例如,对一个 Narray 中的所有元素加 1:
require 'narray'
a = NArray.float([1, 2, 3, 4])
result = a + 1
puts result
  • 矩阵运算:对于二维 Narray,它支持矩阵乘法等运算。假设我们有两个矩阵 ab,进行矩阵乘法:
require 'narray'
a = NArray.float([[1, 2], [3, 4]])
b = NArray.float([[5, 6], [7, 8]])
product = a.matrix_multiply(b)
puts product

这里 matrix_multiply 方法实现了矩阵乘法操作。

2.4 统计运算

Narray 还提供了一些统计运算方法,比如计算平均值、标准差等。

  • 计算平均值
require 'narray'
a = NArray.float([1, 2, 3, 4])
mean = a.mean
puts mean
  • 计算标准差
require 'narray'
a = NArray.float([1, 2, 3, 4])
std_dev = a.std
puts std_dev

这些统计运算方法使得在处理大量数据时快速获取关键统计信息变得非常容易。

3. Ruby 数据分析工具之 SciRuby

SciRuby 是一个用于科学计算的 Ruby 生态系统,它包含了多个用于数据分析和科学计算的库。

3.1 安装 SciRuby

SciRuby 由多个库组成,我们可以通过以下方式安装主要的库:

gem install sciruby

这会安装 SciRuby 的核心库以及一些常用的子库。

3.2 线性代数运算 - LinAlg

LinAlg 是 SciRuby 中用于线性代数运算的库。

  • 矩阵求逆:假设我们有一个矩阵,需要求它的逆矩阵。
require 'sciruby/linalg'
a = SciRuby::NMatrix.new([[1, 2], [3, 4]])
inverse = a.inverse
puts inverse

这里使用 SciRuby::NMatrix 创建矩阵,并通过 inverse 方法求逆矩阵。

  • 求解线性方程组:例如,求解线性方程组 Ax = b,其中 A 是系数矩阵,b 是常数向量。
require 'sciruby/linalg'
A = SciRuby::NMatrix.new([[2, 1], [1, 2]])
b = SciRuby::NMatrix.new([3, 3])
x = A.solve(b)
puts x

solve 方法用于求解线性方程组。

3.3 数值积分 - Quadrature

Quadrature 是 SciRuby 中用于数值积分的库。假设我们要计算函数 f(x) = x^2 在区间 [0, 1] 上的积分。

require 'sciruby/quadrature'
f = lambda { |x| x**2 }
result = SciRuby::Quadrature.new(f, 0, 1).integrate
puts result

这里使用 lambda 定义函数 f,然后通过 SciRuby::Quadrature 类进行数值积分计算。

3.4 曲线拟合 - CurveFit

CurveFit 库用于对数据进行曲线拟合。假设我们有一组数据点,要拟合一个线性函数 y = ax + b

require 'sciruby/curve_fit'
x_data = [1, 2, 3, 4]
y_data = [2, 4, 6, 8]
fit = SciRuby::CurveFit::Linear.new(x_data, y_data)
a, b = fit.coeffs
puts "a: #{a}, b: #{b}"

这里通过 SciRuby::CurveFit::Linear 类对数据进行线性拟合,并获取拟合函数的系数 ab

4. Ruby 数据分析工具之 DataFrames

DataFrames 是一种类似于表格的数据结构,在数据分析中非常常用。在 Ruby 中,我们可以使用 ruby - dataframes 库来处理 DataFrames。

4.1 安装 DataFrames 库

使用 RubyGems 安装:

gem install ruby - dataframes

4.2 创建 DataFrame

  • 从数组创建:假设我们有两个数组,分别表示姓名和年龄,我们可以创建一个 DataFrame。
require 'dataframe'
names = ['Alice', 'Bob', 'Charlie']
ages = [25, 30, 35]
df = DataFrame.new(names: names, ages: ages)
puts df

这里通过 DataFrame.new 方法将两个数组组合成一个 DataFrame,列名分别为 namesages

  • 从 CSV 文件创建:如果有一个 CSV 文件 data.csv,内容如下:
name,age
Alice,25
Bob,30
Charlie,35

我们可以通过以下代码从 CSV 文件创建 DataFrame:

require 'dataframe'
df = DataFrame.read_csv('data.csv')
puts df

4.3 数据选取与过滤

  • 选取列:我们可以选取 DataFrame 中的某一列。例如,选取 ages 列:
require 'dataframe'
names = ['Alice', 'Bob', 'Charlie']
ages = [25, 30, 35]
df = DataFrame.new(names: names, ages: ages)
age_column = df['ages']
puts age_column
  • 过滤行:假设我们要过滤出年龄大于 30 的行:
require 'dataframe'
names = ['Alice', 'Bob', 'Charlie']
ages = [25, 30, 35]
df = DataFrame.new(names: names, ages: ages)
filtered_df = df.filter { |row| row['ages'] > 30 }
puts filtered_df

这里 filter 方法会遍历 DataFrame 的每一行,将符合条件(年龄大于 30)的行保留下来形成新的 DataFrame。

4.4 数据聚合

我们可以对 DataFrame 中的数据进行聚合操作。例如,计算平均年龄:

require 'dataframe'
names = ['Alice', 'Bob', 'Charlie']
ages = [25, 30, 35]
df = DataFrame.new(names: names, ages: ages)
average_age = df.aggregate(:ages, :mean)
puts average_age

这里 aggregate 方法对 ages 列进行了求平均值的聚合操作。

5. Ruby 数据分析工具之 RubyXL

RubyXL 是一个用于处理 Excel 文件的 Ruby 库,在数据分析中,我们常常需要从 Excel 文件中读取数据或者将分析结果写入 Excel 文件。

5.1 安装 RubyXL

使用 RubyGems 安装:

gem install rubyXL

5.2 读取 Excel 文件

假设我们有一个 Excel 文件 data.xlsx,其中有一个工作表包含数据。我们可以读取这个文件并获取数据。

require 'rubyXL'
workbook = RubyXL::Parser.parse('data.xlsx')
worksheet = workbook[0]
worksheet.each do |row|
  row.each do |cell|
    print cell.value, " "
  end
  puts
end

这里通过 RubyXL::Parser.parse 方法读取 Excel 文件,然后遍历工作表中的每一行和每一个单元格,打印出单元格的值。

5.3 写入 Excel 文件

假设我们有一个 DataFrame,要将其写入 Excel 文件。

require 'dataframe'
require 'rubyXL'
names = ['Alice', 'Bob', 'Charlie']
ages = [25, 30, 35]
df = DataFrame.new(names: names, ages: ages)

workbook = RubyXL::Workbook.new
worksheet = workbook.add_worksheet
headers = df.column_names
headers.each_with_index do |header, index|
  worksheet[0][index] = header
end
df.each do |row|
  row_data = row.to_a
  worksheet.add_row(row_data)
end
workbook.write('output.xlsx')

这段代码首先创建一个新的 Excel 工作簿和工作表,将 DataFrame 的列名写入工作表的第一行,然后将 DataFrame 的每一行数据写入工作表,最后保存为 output.xlsx 文件。

6. 综合案例:销售数据分析

现在我们通过一个综合案例来展示如何使用上述工具进行销售数据分析。假设我们有一个销售数据的 CSV 文件 sales.csv,内容如下:

product,region,sales_amount
ProductA,North,1000
ProductB,East,1500
ProductA,West,1200
ProductB,North,900

6.1 数据读取

我们首先使用 ruby - dataframes 库读取数据。

require 'dataframe'
sales_df = DataFrame.read_csv('sales.csv')
puts sales_df

6.2 数据过滤与计算

假设我们要计算北方地区(North)每种产品的总销售额。

require 'dataframe'
sales_df = DataFrame.read_csv('sales.csv')
north_sales = sales_df.filter { |row| row['region'] == 'North' }
product_sales = north_sales.group_by('product').aggregate(:sales_amount, :sum)
puts product_sales

这里先通过 filter 方法过滤出北方地区的销售数据,然后使用 group_by 方法按产品分组,并对每个分组的销售额进行求和。

6.3 数据可视化准备(使用 Narray 辅助计算)

假设我们要将数据可视化,需要先对数据进行一些处理。例如,我们可以将产品和对应的总销售额转换为 Narray 以便后续可能的图形绘制计算。

require 'dataframe'
require 'narray'
sales_df = DataFrame.read_csv('sales.csv')
north_sales = sales_df.filter { |row| row['region'] == 'North' }
product_sales = north_sales.group_by('product').aggregate(:sales_amount, :sum)

products = product_sales['product'].to_a
sales_amounts = product_sales['sales_amount'].to_a

product_narray = NArray.to_na(products)
sales_narray = NArray.to_na(sales_amounts)

这里将产品名称和销售额数据转换为 Narray 对象,方便后续在图形绘制库中使用(虽然这里没有具体展示图形绘制代码,但为其做了数据准备)。

6.4 结果写入 Excel

最后,我们将计算结果写入 Excel 文件。

require 'dataframe'
require 'rubyXL'
sales_df = DataFrame.read_csv('sales.csv')
north_sales = sales_df.filter { |row| row['region'] == 'North' }
product_sales = north_sales.group_by('product').aggregate(:sales_amount, :sum)

workbook = RubyXL::Workbook.new
worksheet = workbook.add_worksheet
headers = product_sales.column_names
headers.each_with_index do |header, index|
  worksheet[0][index] = header
end
product_sales.each do |row|
  row_data = row.to_a
  worksheet.add_row(row_data)
end
workbook.write('north_sales_summary.xlsx')

这段代码将北方地区每种产品的总销售额计算结果写入一个新的 Excel 文件 north_sales_summary.xlsx 中。

通过这个综合案例,我们展示了如何在 Ruby 中利用多种数据分析工具从数据读取、处理、计算到结果输出的完整流程,体现了 Ruby 在数据分析领域的强大能力和灵活性。无论是简单的数据处理任务还是复杂的数据分析项目,Ruby 的这些工具都能提供有效的支持。