Mandelbrot集生成的两种方式

Mandelbrot 集简介

Mandelbrot 集是数学中一个非常著名的分形集合,它以法国数学家本华·曼德勃罗的名字命名。分形是一种具有自相似性质的几何形状,意味着无论放大多少倍,其部分看起来与整体相似。 Mandelbrot 集正是这种特性的典型代表,并且因其复杂而美丽的图形成为了计算机图形学、艺术以及数学研究中的重要主题。

Mandelbrot 集定义于复数平面上,由所有不使序列 $ z_{n+1} = z_n^2 + c $ 发散至无穷大的点 $ c $ 组成,其中 $ z_0 = 0 $。换句话说,对于每一个位于复数平面上的点 $ c $,从 $ z=0 $ 开始应用上述迭代公式,如果该序列保持有界,则点 $ c $ 属于 Mandelbrot 集;反之,如果序列趋向于无穷大,则该点不属于此集合。通常情况下,为了判断一个点是否属于 Mandelbrot 集,会设定一个最大迭代次数和逃逸半径(通常是2),如果在达到最大迭代次数前,序列的模超过了逃逸半径,则认为该点发散。

直接实现方式

直接保存为csv文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#! /usr/bin/env python3
# vim:fenc=utf-8
import numpy as np
# Mandelbrot Set参数
picname = "Mandelbrot"
file_name = f"{picname}.csv"
width, height = 1000, 1000 # 图像的宽度和高度
max_iter = 100 # 最大迭代次数

def mandelbrot_set(width, height, max_iter):
x = np.linspace(-2.5, 1.5, width)
y = np.linspace(-2, 2, height)
escape_time = np.zeros((height, width)) # 注意这里的维度顺序

for i in range(width):
for j in range(height):
c = complex(x[i], y[j])
z = 0
n = 0
while abs(z) <= 2 and n < max_iter:
z = z*z + c
n += 1
escape_time[j, i] = n # 根据像素位置更新逃逸时间

return x, y, escape_time

# 计算Mandelbrot集
x_coords, y_coords, escape_time = mandelbrot_set(width, height, max_iter)

# 将结果保存为适合Veusz导入的格式
with open(file_name, 'w') as file:
# 写入X坐标行
file.write(',' + ','.join(map(str, x_coords)) + '\n')
for j in range(escape_time.shape[0]):
# 写入每行的数据,先写Y坐标,然后是该行的逃逸时间值
file.write(str(y_coords[j]) + ',' + ','.join(map(str, escape_time[j])) + '\n')

print(f"Mandelbrot集已成功保存到{file_name}")

使用 Pandas 库保存数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#! /usr/bin/env python3
# vim:fenc=utf-8
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

def mandelbrot(c, max_iter):
z = 0
n = 0
while abs(z) <= 2 and n < max_iter:
z = z*z + c
n += 1
return n

def mandelbrot_set(xmin, xmax, ymin, ymax, width, height, max_iter):
r1 = np.linspace(xmin, xmax, width)
r2 = np.linspace(ymin, ymax, height)
m = np.empty((width,height))
for i in range(width):
for j in range(height):
m[i,j] = mandelbrot(r1[i] + 1j*r2[j], max_iter)
return m, r1, r2 # 返回m以及对应的x和y坐标值

# 设置参数并生成Mandelbrot集合
xmin, xmax, ymin, ymax = -2.0, 1.0, -1.5, 1.5
width, height = 800, 800
max_iter = 256

m, r1, r2 = mandelbrot_set(xmin, xmax, ymin, ymax, width, height, max_iter)

# 显示图像(可选)
# plt.imshow(m.T, extent=[xmin, xmax, ymin, ymax], cmap='hot', interpolation='bilinear')
# plt.colorbar()
# plt.title("Mandelbrot Set")
# plt.show()

# 将结果保存为CSV文件
# 创建一个列表来保存数据点
data_points = []
for i in range(width):
for j in range(height):
data_points.append([r1[i], r2[j], m[i, j]])

# 使用pandas DataFrame保存数据
df = pd.DataFrame(data_points, columns=['Re', 'Im', 'Iteration'])
df.to_csv('mandelbrot_set.csv', index=False)

print("Mandelbrot集合已成功保存至mandelbrot_set.csv")

Pandas 保存数据与直接保存数据的不同

在处理和存储数据时,使用Pandas的DataFrame来保存数据与直接保存数据(例如将数据保存为纯文本、CSV文件等)有着显著的区别。以下是这两种方法的主要不同点:

使用 Pandas DataFrame保存数据

结构化存储

  • 表格形式DataFrame提供了一个二维表格结构,支持行和列标签,并允许每列有不同的数据类型。
  • 强大的数据操作能力:内置了丰富的函数用于数据清洗、转换、筛选、聚合等高级功能。

索引和标签支持

  • 灵活访问:可以通过列名、行位置或布尔索引来选取子集,便于快速定位所需信息。
  • 多级索引:支持复杂的索引机制,使得数据管理和查询更加灵活。

缺失值处理

  • 自动管理缺失数据:通过NaN表示缺失值,并提供了多种方法来清理或填补这些缺失值。

数据可视化和分析集成

  • 与其他库的良好集成:可以方便地与NumPy、Matplotlib、Seaborn等科学计算和可视化库结合使用,增强数据分析能力。

直接保存数据

简单的数据格式

  • 通用性高:直接存储的数据通常保存为原始格式,如CSV、TXT、JSON等,适合于结构相对简单、规模较小的数据集。
  • 轻量级:这种保存方式不依赖于外部库,适合需要跨平台使用的场景。

有限的数据处理能力

  • 缺乏高级特性:直接存储的数据没有内置的数据处理功能,如果需要进行数据处理,则需编写额外的代码或使用其他工具。
  • 基础操作:虽然可以直接读写数据,但复杂的数据操作如过滤、分组、聚合等需要额外的努力来实现。

通用性和可移植性

  • 易于分享:由于直接存储的数据格式通常是通用的,因此可以在不同的编程语言和环境中读取和写入,增加了跨平台使用的便利性。

总的来说,选择哪种方式取决于具体的应用需求和数据特点。DataFrame 提供了一种更为强大和灵活的方式来存储和处理数据,特别适用于复杂的数据分析任务;而直接保存数据更适合于简单场景,或者当你需要一种轻量级、跨平台的数据交换方式时。