转载请注明出处:小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你,欢迎[点赞、收藏、关注]哦~
目录
np.fromiter
np.fromiter
是 NumPy 提供的一个函数,用于从可迭代对象(如生成器、列表等)创建一个 NumPy 数组。它直接从可迭代对象中逐个读取数据,适合在数据量较大或数据生成过程中节省内存的场景。
优点:
np.array
更快。缺点:
np.array
np.array
是 NumPy 最常用的函数之一,用于将输入数据(如列表、元组、嵌套序列等)转换为 NumPy 数组。它会一次性读取输入数据并将其存储到内存中的连续块中,适合在数据已经加载到内存中的场景。
优点:
缺点:
np.fromiter
。import numpy as np
import time
import pandas as pd
import matplotlib.pyplot as plt
# 测试数据生成函数
def generate_data(size):
return range(size) # 使用生成器来模拟大量数据
# 测试 np.fromiter 的性能
def test_fromiter_int32(data):
start_time = time.time()
np.fromiter(data, dtype=np.int32)
return time.time() - start_time
# 测试 np.array 的性能(不计算 list 开销)
def test_array_no_list_overhead(data):
data = list(data) # 先将生成器转换为列表
start_time = time.time()
np.array(data, dtype=np.int32) # 确保 dtype 为 int32
return time.time() - start_time
# 测试 np.array 的性能(计算 list 开销)
def test_array_with_list_overhead(data):
start_time = time.time()
data = list(data) # 生成器转换为列表的时间也包含在内
np.array(data, dtype=np.int32) # 确保 dtype 为 int32
return time.time() - start_time
# 数据量从 10^1 到 10^9
data_sizes = [10**i for i in range(1, 8)] # 从 10^1 到 10^7
results_comparison = []
for size in data_sizes:
data = generate_data(size)
# np.fromiter 性能测试
fromiter_time_int32 = test_fromiter_int32(data)
# np.array 性能测试(不计算 list 开销)
data = generate_data(size) # 重新生成数据
array_time_no_list_overhead = test_array_no_list_overhead(data)
# np.array 性能测试(计算 list 开销)
data = generate_data(size) # 重新生成数据
array_time_with_list_overhead = test_array_with_list_overhead(data)
results_comparison.append((size, fromiter_time_int32, array_time_no_list_overhead, array_time_with_list_overhead))
# 将结果显示为数据框
df_results_comparison = pd.DataFrame(results_comparison, columns=[
'Data Size', 'Fromiter Time (s)', 'Array Time without List Overhead (s)', 'Array Time with List Overhead (s)'
])
# 绘制比较性能曲线
plt.figure(figsize=(10, 6))
plt.plot(df_results_comparison['Data Size'], df_results_comparison['Fromiter Time (s)'], marker='o', label='np.fromiter (int32)')
plt.plot(df_results_comparison['Data Size'], df_results_comparison['Array Time without List Overhead (s)'], marker='o', label='np.array without list overhead (int32)')
plt.plot(df_results_comparison['Data Size'], df_results_comparison['Array Time with List Overhead (s)'], marker='o', label='np.array with list overhead (int32)')
plt.xlabel('Data Size')
plt.ylabel('Time (s)')
plt.xscale('log') # 使用对数刻度显示更大范围的数据
plt.yscale('log') # 使用对数刻度显示时间差异
plt.title('Performance Comparison: np.fromiter vs np.array (dtype=int32)')
plt.legend()
plt.grid(True)
plt.show()
从实验结果和图表中,我们可以观察到 np.fromiter
、np.array
(不计算列表开销)和 np.array
(计算列表开销)在不同数据量下的性能表现差异。以下是对实验结果的详细分析:
1. 小数据量 (10^1
到 10^3
)
10^1
到 10^3
),三种方法的执行时间差异非常小。此时,数据的处理开销可以忽略不计,所有方法的性能表现几乎相同。np.fromiter
稍慢:在这些小数据量下,np.fromiter
的执行时间稍微比 np.array
长。这是因为 np.fromiter
需要逐个元素地从生成器中读取数据,而 np.array
直接操作列表(尤其是不计算列表开销时)。2. 中等数据量 (10^4
到 10^5
)
10^4
及以上时,np.array
方法开始表现出性能差异。特别是,当我们计算列表转换开销时,np.array
的执行时间开始显著增加。np.fromiter
表现稳定:np.fromiter
在中等数据量下表现相对稳定,时间随数据量线性增长,这表明其适合处理较大规模的数据。3. 大数据量 (10^6
及以上)
np.array
的开销显著增加:对于 10^5
以上的数据量,包含列表转换的 np.array
方法的执行时间显著增加,表明当数据量很大时,列表转换开销成为一个显著的瓶颈。np.fromiter
和不包含列表转换的 np.array
方法更优:在处理大数据时,这两种方法的时间相对较低,尤其是不计算列表开销的 np.array
方法,在大数据量下明显比计算列表开销的 np.array
更快。np.fromiter
的优势:当处理非常大的数据量且数据来源是生成器时,np.fromiter
表现得非常稳定且高效,适合处理大数据量。np.array
(不包含列表开销)适合已有数据结构:如果你已经有一个数据结构(如列表),并且需要将其转换为 NumPy 数组,那么不包含列表转换的 np.array
是最有效的选择。np.fromiter
或直接将列表转换为数组,而不是将生成器转换为列表再转为数组。还有一种情况,如果变量aaa已经是tensor了,那么使用aaa.numpy()比以上方法都高效!
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。