
👋 大家好,欢迎来到我的技术博客! 📚 在这里,我会分享学习笔记、实战经验与技术思考,力求用简单的方式讲清楚复杂的问题。 🎯 本文将围绕NumPy这个话题展开,希望能为你带来一些启发或实用的参考。 🌱 无论你是刚入门的新手,还是正在进阶的开发者,希望你都能有所收获!
文章目录
- Python NumPy 数组拼接:深入理解 concatenate 函数的横向与纵向拼接 🧠
-
- 什么是 NumPy concatenate 函数?🔍
- 理解轴(Axis)的概念 🎯
- 一维数组的拼接操作 💡
- 二维数组的横向拼接 🔄
- 二维数组的纵向拼接 ⬇️
- 多维数组的拼接操作 📐
- 处理不兼容数组的拼接 ❌
- 性能优化技巧 ⚡
- 实际应用场景 🌟
-
- 数据清洗和预处理
- 时间序列数据处理
- 图像处理中的应用
- 与其他拼接函数的比较 🆚
- 高级技巧和最佳实践 🎯
-
- 条件性拼接
- 动态拼接策略
- 内存友好的拼接
- 错误处理和调试技巧 🔧
- 实战案例分析 📊
- 总结与展望 🎉
Python NumPy 数组拼接:深入理解 concatenate 函数的横向与纵向拼接 🧠
在数据科学和机器学习的世界中,数组操作是日常工作的核心部分。NumPy 作为 Python 中最基础且强大的数值计算库,提供了丰富的数组操作功能。其中,concatenate 函数是进行数组拼接的核心工具之一。今天,我们将深入探讨这个函数的各种用法,从基础概念到高级应用,帮助你全面掌握数组拼接的艺术。🎨
什么是 NumPy concatenate 函数?🔍
numpy.concatenate 是一个用于沿指定轴连接一系列数组的函数。它允许我们将多个数组按照特定的方式组合在一起,形成一个新的、更大的数组。这个函数的基本语法如下:
numpy.concatenate((a1, a2, ...), axis=0, out=None)
其中:
- a1, a2, …:需要连接的数组序列
- axis:连接的轴,默认为0
- out:可选参数,用于指定输出数组
让我们从最简单的例子开始:
import numpy as np
# 创建两个一维数组
arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])
# 横向拼接(默认axis=0)
result = np.concatenate((arr1, arr2))
print("一维数组拼接结果:", result)
# 输出: [1 2 3 4 5 6]
理解轴(Axis)的概念 🎯
在深入学习之前,我们需要先理解"轴"的概念。轴是数组维度的索引,对于二维数组来说:
- axis=0 表示沿着行的方向(纵向)
- axis=1 表示沿着列的方向(横向)
# 创建两个二维数组
matrix1 = np.array([[1, 2],
[3, 4]])
matrix2 = np.array([[5, 6],
[7, 8]])
print("矩阵1:")
print(matrix1)
print("\\n矩阵2:")
print(matrix2)
# axis=0 纵向拼接
vertical_concat = np.concatenate((matrix1, matrix2), axis=0)
print("\\n纵向拼接 (axis=0):")
print(vertical_concat)
# axis=1 横向拼接
horizontal_concat = np.concatenate((matrix1, matrix2), axis=1)
print("\\n横向拼接 (axis=1):")
print(horizontal_concat)
为了更直观地理解这个概念,让我们看一个 mermaid 图表来展示不同轴拼接的效果:
渲染错误: Mermaid 渲染失败: Parse error on line 2: …] –> B[Matrix1
[[1,2],
[3 ———————–^ Expecting 'SQE', 'DOUBLECIRCLEEND', 'PE', '-)', 'STADIUMEND', 'SUBROUTINEEND', 'PIPE', 'CYLINDEREND', 'DIAMOND_STOP', 'TAGEND', 'TRAPEND', 'INVTRAPEND', 'UNICODE_TEXT', 'TEXT', 'TAGSTART', got 'SUBROUTINESTART'
一维数组的拼接操作 💡
对于一维数组,拼接操作相对简单,因为只有一个轴(axis=0)。让我们探索一些具体的例子:
# 基本的一维数组拼接
arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])
arr3 = np.array([7, 8, 9])
# 连续拼接多个数组
result = np.concatenate((arr1, arr2, arr3))
print("连续拼接三个数组:", result)
# 输出: [1 2 3 4 5 6 7 8 9]
# 使用列表推导式进行批量拼接
arrays = [np.array([i, i+1]) for i in range(1, 10, 2)]
combined = np.concatenate(arrays)
print("批量拼接结果:", combined)
# 输出: [1 2 3 4 5 6 7 8 9 10]
需要注意的是,当处理一维数组时,只能使用 axis=0,因为一维数组只有一个维度:
# 尝试使用其他轴会导致错误
try:
result = np.concatenate((arr1, arr2), axis=1)
except np.AxisError as e:
print(f"错误信息: {e}")
# 错误信息: axis 1 is out of bounds for array of dimension 1
二维数组的横向拼接 🔄
横向拼接是指将数组按列方向连接起来。这在处理表格数据时特别有用,比如合并不同的特征列。
# 创建示例数据
features1 = np.array([[1, 2],
[3, 4],
[5, 6]])
features2 = np.array([[7, 8],
[9, 10],
[11, 12]])
labels = np.array([[0],
[1],
[0]])
print("特征矩阵1:")
print(features1)
print("\\n特征矩阵2:")
print(features2)
print("\\n标签矩阵:")
print(labels)
# 横向拼接多个数组
combined_features = np.concatenate((features1, features2), axis=1)
print("\\n横向拼接特征矩阵:")
print(combined_features)
# 同时拼接特征和标签
complete_data = np.concatenate((features1, features2, labels), axis=1)
print("\\n完整的数据集:")
print(complete_data)
在实际应用中,横向拼接常用于数据预处理阶段,例如将不同的特征组合成一个完整的特征矩阵:
# 模拟真实场景:用户数据拼接
user_ids = np.array([[1001], [1002], [1003], [1004]])
ages = np.array([[25], [30], [35], [28]])
incomes = np.array([[50000], [75000], [90000], [60000]])
purchase_history = np.array([[3], [7], [12], [5]])
# 拼接所有用户特征
user_data = np.concatenate((user_ids, ages, incomes, purchase_history), axis=1)
print("用户数据汇总:")
print(user_data)
print("\\n列含义: [用户ID, 年龄, 收入, 购买历史]")
二维数组的纵向拼接 ⬇️
纵向拼接是指将数组按行方向连接起来,这是最常见的拼接方式之一,特别是在合并来自不同来源但结构相同的数据时。
# 创建两个具有相同列数但不同行数的数组
batch1 = np.array([[1, 2, 3],
[4, 5, 6]])
batch2 = np.array([[7, 8, 9],
[10, 11, 12],
[13, 14, 15]])
print("批次1数据:")
print(batch1)
print("\\n批次2数据:")
print(batch2)
# 纵向拼接
combined_batches = np.concatenate((batch1, batch2), axis=0)
print("\\n纵向拼接后的完整数据:")
print(combined_batches)
纵向拼接的一个重要应用场景是在机器学习中合并训练数据:
# 模拟训练数据合并
train_set_1 = np.random.rand(100, 5) # 100个样本,5个特征
train_set_2 = np.random.rand(150, 5) # 150个样本,5个特征
train_set_3 = np.random.rand(75, 5) # 75个样本,5个特征
# 合并所有训练数据
full_training_set = np.concatenate((train_set_1, train_set_2, train_set_3), axis=0)
print(f"合并后训练集形状: {full_training_set.shape}")
# 输出: 合并后训练集形状: (325, 5)
多维数组的拼接操作 📐
随着维度的增加,拼接操作变得更加灵活但也更加复杂。让我们看看三维数组的拼接:
# 创建三维数组
cube1 = np.array([[[1, 2], [3, 4]],
[[5, 6], [7, 8]]])
cube2 = np.array([[[9, 10], [11, 12]],
[[13, 14], [15, 16]]])
print("立方体1:")
print(cube1)
print("\\n立方体2:")
print(cube2)
# axis=0: 在第一个维度上拼接
result_axis0 = np.concatenate((cube1, cube2), axis=0)
print(f"\\naxis=0 拼接结果形状: {result_axis0.shape}")
print(result_axis0)
# axis=1: 在第二个维度上拼接
result_axis1 = np.concatenate((cube1, cube2), axis=1)
print(f"\\naxis=1 拼接结果形状: {result_axis1.shape}")
print(result_axis1)
# axis=2: 在第三个维度上拼接
result_axis2 = np.concatenate((cube1, cube2), axis=2)
print(f"\\naxis=2 拼接结果形状: {result_axis2.shape}")
print(result_axis2)
处理不兼容数组的拼接 ❌
在实际应用中,我们经常会遇到形状不匹配的数组。了解如何处理这些情况非常重要:
# 形状不匹配的情况
arr1 = np.array([[1, 2, 3], [4, 5, 6]]) # shape: (2, 3)
arr2 = np.array([[7, 8], [9, 10], [11, 12]]) # shape: (3, 2)
print("数组1形状:", arr1.shape)
print("数组2形状:", arr2.shape)
# 尝试直接拼接会失败
try:
result = np.concatenate((arr1, arr2), axis=0)
except ValueError as e:
print(f"拼接失败: {e}")
# 解决方案1: 调整数组形状使其兼容
# 方法1: 重新组织数据以匹配维度
arr2_transposed = arr2.T # 转置使形状变为 (2, 3)
compatible_result = np.concatenate((arr1, arr2_transposed), axis=0)
print("\\n调整后拼接结果:")
print(compatible_result)
# 解决方案2: 使用填充来使数组尺寸一致
def pad_arrays_for_concatenation(arrays, axis=0):
"""通过填充使数组可以拼接"""
shapes = [arr.shape for arr in arrays]
max_shape = list(shapes[0])
# 找到每个维度的最大尺寸
for shape in shapes[1:]:
for i in range(len(shape)):
if i < len(max_shape):
max_shape[i] = max(max_shape[i], shape[i])
else:
max_shape.append(shape[i])
# 填充所有数组到相同的最大尺寸
padded_arrays = []
for arr in arrays:
padding = []
for i in range(len(max_shape)):
if i < len(arr.shape):
padding.append((0, max_shape[i] – arr.shape[i]))
else:
padding.append((0, max_shape[i]))
padded_arr = np.pad(arr, padding, mode='constant', constant_values=0)
padded_arrays.append(padded_arr)
return np.concatenate(padded_arrays, axis=axis)
# 示例:拼接不同形状的数组
irregular_arr1 = np.array([[1, 2], [3, 4]])
irregular_arr2 = np.array([[5, 6, 7]])
padded_result = pad_arrays_for_concatenation([irregular_arr1, irregular_arr2], axis=0)
print("\\n填充后拼接结果:")
print(padded_result)
性能优化技巧 ⚡
在处理大型数组时,性能是一个重要的考虑因素。以下是一些优化拼接操作的技巧:
import time
# 创建大型数组进行性能测试
large_array1 = np.random.rand(10000, 1000)
large_array2 = np.random.rand(5000, 1000)
# 方法1: 直接拼接
start_time = time.time()
result1 = np.concatenate((large_array1, large_array2), axis=0)
time1 = time.time() – start_time
print(f"直接拼接耗时: {time1:.4f} 秒")
# 方法2: 预分配内存空间
start_time = time.time()
total_rows = large_array1.shape[0] + large_array2.shape[0]
result2 = np.empty((total_rows, large_array1.shape[1]))
result2[:large_array1.shape[0]] = large_array1
result2[large_array1.shape[0]:] = large_array2
time2 = time.time() – start_time
print(f"预分配内存拼接耗时: {time2:.4f} 秒")
# 对于已知最终大小的情况,预先创建目标数组可能更快
另一个重要的性能优化技巧是避免在循环中重复拼接数组:
# 不推荐的做法:在循环中反复拼接
def inefficient_concatenation(arrays):
result = np.array([])
for arr in arrays:
result = np.concatenate((result, arr))
return result
# 推荐的做法:收集所有数组然后一次性拼接
def efficient_concatenation(arrays):
return np.concatenate(arrays)
# 性能对比
test_arrays = [np.random.rand(1000) for _ in range(100)]
# 测试低效方法
start_time = time.time()
result_slow = inefficient_concatenation(test_arrays)
time_slow = time.time() – start_time
# 测试高效方法
start_time = time.time()
result_fast = efficient_concatenation(test_arrays)
time_fast = time.time() – start_time
print(f"低效方法耗时: {time_slow:.4f} 秒")
print(f"高效方法耗时: {time_fast:.4f} 秒")
print(f"性能提升: {time_slow/time_fast:.2f} 倍")
实际应用场景 🌟
数据清洗和预处理
在数据分析项目中,经常需要合并来自不同源的数据:
# 模拟数据清洗场景
def merge_datasets(dataset_list):
"""
合并多个数据集,自动处理缺失值和不一致的列
"""
# 假设所有数据集都有相同的列结构
# 实际应用中可能需要更多的预处理步骤
# 过滤掉空的数据集
valid_datasets = [ds for ds in dataset_list if ds.size > 0]
if not valid_datasets:
return np.array([])
# 合并所有有效的数据集
merged_data = np.concatenate(valid_datasets, axis=0)
return merged_data
# 示例数据集
dataset1 = np.array([[1, 'A', 10.5], [2, 'B', 20.3], [3, 'C', 15.7]])
dataset2 = np.array([[4, 'D', 12.1], [5, 'E', 18.9]])
dataset3 = np.array([[6, 'F', 22.4]])
# 注意:这里为了简化示例,使用了字符串混合数组
# 在实际应用中,建议保持数值类型一致性
时间序列数据处理
在金融或物联网应用中,时间序列数据的拼接非常常见:
# 模拟股票价格数据拼接
def combine_stock_data(daily_data, weekly_data, monthly_data):
"""
组合不同频率的股票数据
"""
# 假设所有数据都已经被预处理为相同格式
# 格式: [日期戳, 开盘价, 最高价, 最低价, 收盘价, 成交量]
# 按时间顺序排序所有数据
all_data = np.concatenate([daily_data, weekly_data, monthly_data], axis=0)
# 按日期排序(假设第一列为日期戳)
sorted_indices = np.argsort(all_data[:, 0])
sorted_data = all_data[sorted_indices]
return sorted_data
# 示例数据
daily_prices = np.array([
[20230101, 100.5, 102.3, 99.8, 101.2, 1000000],
[20230102, 101.2, 103.1, 100.5, 102.8, 1200000]
])
weekly_prices = np.array([
[20230108, 102.8, 105.2, 101.5, 104.7, 8000000]
])
monthly_prices = np.array([
[20230201, 104.7, 110.3, 103.2, 109.8, 25000000]
])
# 合并数据
combined_stock_data = combine_stock_data(daily_prices, weekly_prices, monthly_prices)
print("合并后的股票数据:")
print(combined_stock_data)
图像处理中的应用
在计算机视觉任务中,图像数据的拼接也很常见:
# 模拟图像通道拼接
def merge_image_channels(red_channel, green_channel, blue_channel):
"""
将分离的RGB通道合并成彩色图像
"""
# 确保所有通道形状一致
assert red_channel.shape == green_channel.shape == blue_channel.shape
# 将三个单通道图像合并成三通道图像
# 假设输入是二维灰度图像,输出是三维彩色图像
height, width = red_channel.shape
rgb_image = np.zeros((height, width, 3))
rgb_image[:, :, 0] = red_channel # R通道
rgb_image[:, :, 1] = green_channel # G通道
rgb_image[:, :, 2] = blue_channel # B通道
return rgb_image
# 或者使用 concatenate 直接拼接
def merge_channels_with_concatenate(channels):
"""
使用 concatenate 合并图像通道
"""
# 将所有通道扩展为三维数组然后拼接
expanded_channels = [channel[:, :, np.newaxis] for channel in channels]
return np.concatenate(expanded_channels, axis=2)
# 示例:模拟图像数据
red = np.random.randint(0, 256, (100, 100))
green = np.random.randint(0, 256, (100, 100))
blue = np.random.randint(0, 256, (100, 100))
# 合并通道
rgb_image = merge_channels_with_concatenate([red, green, blue])
print(f"合成图像形状: {rgb_image.shape}") # 应该是 (100, 100, 3)
与其他拼接函数的比较 🆚
NumPy 提供了多种拼接函数,了解它们的区别很重要:
# 创建测试数据
arr1 = np.array([[1, 2], [3, 4]])
arr2 = np.array([[5, 6], [7, 8]])
print("原始数组1:")
print(arr1)
print("\\n原始数组2:")
print(arr2)
# 1. concatenate – 最通用的方法
concat_result = np.concatenate((arr1, arr2), axis=0)
print("\\nconcatenate 结果:")
print(concat_result)
# 2. vstack – 垂直堆叠(等同于 axis=0 的 concatenate)
vstack_result = np.vstack((arr1, arr2))
print("\\nvstack 结果:")
print(vstack_result)
print(f"vstack 和 concatenate 结果是否相同: {np.array_equal(concat_result, vstack_result)}")
# 3. hstack – 水平堆叠(等同于 axis=1 的 concatenate)
hstack_result = np.hstack((arr1, arr2))
print("\\nhstack 结果:")
print(hstack_result)
# 4. dstack – 深度堆叠(沿第三轴堆叠)
dstack_result = np.dstack((arr1, arr2))
print("\\ndstack 结果:")
print(dstack_result)
print(f"dstack 结果形状: {dstack_result.shape}")
# 5. column_stack – 列堆叠(对一维数组特别有用)
col1 = np.array([1, 2, 3])
col2 = np.array([4, 5, 6])
column_stack_result = np.column_stack((col1, col2))
print("\\ncolumn_stack 结果:")
print(column_stack_result)
# 6. row_stack – 行堆叠(等同于 vstack)
row_stack_result = np.row_stack((arr1, arr2))
print("\\nrow_stack 结果:")
print(row_stack_result)
每种函数都有其特定的用途:
- concatenate: 最灵活,可以指定任意轴
- vstack: 专门用于垂直堆叠
- hstack: 专门用于水平堆叠
- dstack: 专门用于深度堆叠
- column_stack: 特别适合构建列数据
- row_stack: 专门用于行堆叠
高级技巧和最佳实践 🎯
条件性拼接
有时我们需要根据条件来决定是否拼接某些数组:
def conditional_concatenate(arrays, conditions):
"""
根据条件选择性地拼接数组
"""
selected_arrays = [arr for arr, cond in zip(arrays, conditions) if cond]
if not selected_arrays:
return np.array([])
return np.concatenate(selected_arrays, axis=0)
# 示例
data_arrays = [
np.array([[1, 2], [3, 4]]),
np.array([[5, 6], [7, 8]]),
np.array([[9, 10], [11, 12]])
]
conditions = [True, False, True] # 只选择第一个和第三个数组
result = conditional_concatenate(data_arrays, conditions)
print("条件拼接结果:")
print(result)
动态拼接策略
在处理不确定数量的数组时,动态拼接策略很有用:
def dynamic_concatenate(*arrays, axis=0, strategy='auto'):
"""
动态拼接数组,支持不同的策略
"""
if not arrays:
return np.array([])
if strategy == 'auto':
# 自动检测最优策略
if len(arrays) == 1:
return arrays[0]
elif len(arrays) <= 10:
# 小数量直接拼接
return np.concatenate(arrays, axis=axis)
else:
# 大数量分批处理
batch_size = 100
result = arrays[0]
for i in range(1, len(arrays), batch_size):
batch = arrays[i:i+batch_size]
batch_result = np.concatenate(batch, axis=axis)
result = np.concatenate((result, batch_result), axis=axis)
return result
return np.concatenate(arrays, axis=axis)
# 测试不同规模的数据
small_arrays = [np.random.rand(10, 5) for _ in range(5)]
medium_arrays = [np.random.rand(100, 50) for _ in range(50)]
large_arrays = [np.random.rand(1000, 100) for _ in range(200)]
print(f"小规模拼接结果形状: {dynamic_concatenate(*small_arrays).shape}")
print(f"中等规模拼接结果形状: {dynamic_concatenate(*medium_arrays).shape}")
内存友好的拼接
处理超大数组时,内存管理至关重要:
def memory_efficient_concatenate(array_generator, axis=0, chunk_size=1000):
"""
内存友好的拼接方法,适用于大数据集
"""
chunks = []
current_chunk = []
current_size = 0
for array in array_generator:
current_chunk.append(array)
current_size += array.shape[axis] if axis < len(array.shape) else 1
if current_size >= chunk_size:
# 拼接当前块
chunk = np.concatenate(current_chunk, axis=axis)
chunks.append(chunk)
current_chunk = []
current_size = 0
# 处理剩余的数据
if current_chunk:
chunk = np.concatenate(current_chunk, axis=axis)
chunks.append(chunk)
# 最终拼接所有块
if not chunks:
return np.array([])
elif len(chunks) == 1:
return chunks[0]
else:
return np.concatenate(chunks, axis=axis)
# 示例:生成器模式
def data_generator(num_arrays, array_shape):
"""模拟数据生成器"""
for i in range(num_arrays):
yield np.random.rand(*array_shape)
# 使用内存友好方式处理大量数据
result = memory_efficient_concatenate(
data_generator(1000, (100, 50)),
axis=0,
chunk_size=50
)
print(f"内存友好拼接结果形状: {result.shape}")
错误处理和调试技巧 🔧
良好的错误处理是专业代码的重要组成部分:
def safe_concatenate(arrays, axis=0, fill_value=0):
"""
安全的拼接函数,包含详细的错误处理
"""
try:
# 输入验证
if not isinstance(arrays, (list, tuple)):
raise TypeError("输入必须是数组列表或元组")
if len(arrays) == 0:
return np.array([])
if len(arrays) == 1:
return np.asarray(arrays[0])
# 检查所有数组
validated_arrays = []
base_shape = None
for i, arr in enumerate(arrays):
arr = np.asarray(arr)
if base_shape is None:
base_shape = list(arr.shape)
else:
# 检查除拼接轴外的所有维度是否匹配
if len(arr.shape) != len(base_shape):
raise ValueError(f"数组 {i} 的维度数 ({len(arr.shape)}) 与第一个数组 ({len(base_shape)}) 不匹配")
for dim in range(len(base_shape)):
if dim != axis and base_shape[dim] != arr.shape[dim]:
raise ValueError(f"数组 {i} 在维度 {dim} 上的大小 ({arr.shape[dim]}) 与第一个数组 ({base_shape[dim]}) 不匹配")
validated_arrays.append(arr)
return np.concatenate(validated_arrays, axis=axis)
except Exception as e:
print(f"拼接过程中发生错误: {type(e).__name__}: {e}")
raise
# 测试错误处理
try:
# 正常情况
normal_arrays = [np.array([[1, 2], [3, 4]]), np.array([[5, 6], [7, 8]])]
result = safe_concatenate(normal_arrays, axis=0)
print("正常拼接成功:")
print(result)
# 异常情况
problematic_arrays = [np.array([[1, 2], [3, 4]]), np.array([[5, 6, 7], [7, 8, 9]])]
result = safe_concatenate(problematic_arrays, axis=0)
except ValueError as e:
print(f"捕获到预期错误: {e}")
实战案例分析 📊
让我们通过一个完整的实战案例来巩固所学知识:
class DataProcessor:
"""
数据处理器类,演示各种拼接操作的实际应用
"""
def __init__(self):
self.processed_data = None
def load_batch_data(self, file_paths):
"""
模拟从多个文件加载数据批次
"""
batches = []
for path in file_paths:
# 模拟数据加载
batch_size = np.random.randint(50, 150)
batch = np.random.rand(batch_size, 10) # 10个特征
batches.append(batch)
print(f"从 {path} 加载了 {batch_size} 条记录")
return batches
def process_and_merge_batches(self, file_paths):
"""
处理并合并多个数据批次
"""
print("开始处理数据批次…")
# 加载数据
batches = self.load_batch_data(file_paths)
# 数据预处理(示例:标准化)
processed_batches = []
for i, batch in enumerate(batches):
# 简单的标准化处理
mean_vals = np.mean(batch, axis=0)
std_vals = np.std(batch, axis=0)
# 避免除零错误
std_vals[std_vals == 0] = 1
normalized_batch = (batch – mean_vals) / std_vals
processed_batches.append(normalized_batch)
print(f"批次 {i+1} 处理完成")
# 合并所有批次
print("开始合并数据…")
self.processed_data = np.concatenate(processed_batches, axis=0)
print(f"合并完成!总数据量: {self.processed_data.shape[0]} 条记录")
return self.processed_data
def add_new_features(self, new_feature_data):
"""
添加新特征到现有数据
"""
if self.processed_data is None:
raise ValueError("请先处理数据再添加新特征")
# 确保新特征数据与现有数据行数匹配
if new_feature_data.shape[0] != self.processed_data.shape[0]:
raise ValueError(f"新特征数据行数 ({new_feature_data.shape[0]}) 与现有数据 ({self.processed_data.shape[0]}) 不匹配")
# 横向拼接新特征
self.processed_data = np.concatenate([self.processed_data, new_feature_data], axis=1)
print(f"添加新特征完成!新数据形状: {self.processed_data.shape}")
return self.processed_data
def split_train_test(self, test_ratio=0.2):
"""
分割训练集和测试集
"""
if self.processed_data is None:
raise ValueError("没有可用的数据进行分割")
total_samples = self.processed_data.shape[0]
test_size = int(total_samples * test_ratio)
train_size = total_samples – test_size
# 随机打乱数据
indices = np.random.permutation(total_samples)
train_indices = indices[:train_size]
test_indices = indices[train_size:]
train_data = self.processed_data[train_indices]
test_data = self.processed_data[test_indices]
print(f"数据分割完成: 训练集 {train_data.shape[0]} 条,测试集 {test_data.shape[0]} 条")
return train_data, test_data
# 使用示例
processor = DataProcessor()
# 模拟文件路径
file_paths = ['data_batch_1.csv', 'data_batch_2.csv', 'data_batch_3.csv']
# 处理和合并数据
merged_data = processor.process_and_merge_batches(file_paths)
# 添加新特征
new_features = np.random.rand(merged_data.shape[0], 3) # 3个新特征
enhanced_data = processor.add_new_features(new_features)
# 分割训练测试集
train_set, test_set = processor.split_train_test(test_ratio=0.25)
print(f"\\n最终结果:")
print(f"- 合并数据形状: {merged_data.shape}")
print(f"- 增强数据形状: {enhanced_data.shape}")
print(f"- 训练集形状: {train_set.shape}")
print(f"- 测试集形状: {test_set.shape}")
总结与展望 🎉
通过这篇文章的学习,我们深入了解了 NumPy concatenate 函数的强大功能和灵活应用。从基础的一维数组拼接到复杂的多维数组操作,从简单的横向纵向拼接到高级的性能优化技巧,我们覆盖了数组拼接的各个方面。
关键要点回顾:
NumPy 的数组拼接功能在数据科学、机器学习、图像处理等领域都有着广泛的应用。掌握这些技能不仅能够提高编程效率,还能让你更好地理解和处理复杂的数据结构。
如果你想进一步深入学习 NumPy 和相关技术,我推荐参考以下资源:
- NumPy 官方文档 提供了最权威和详细的技术说明
- SciPy Lecture Notes 包含了丰富的科学计算教程
- Python Data Science Handbook 是一本优秀的数据科学入门书籍
随着人工智能和大数据时代的到来,高效的数组操作能力变得越来越重要。希望本文能够帮助你在数据处理的道路上走得更远、更稳!🚀
🙌 感谢你读到这里! 🔍 技术之路没有捷径,但每一次阅读、思考和实践,都在悄悄拉近你与目标的距离。 💡 如果本文对你有帮助,不妨 👍 点赞、📌 收藏、📤 分享 给更多需要的朋友! 💬 欢迎在评论区留下你的想法、疑问或建议,我会一一回复,我们一起交流、共同成长 🌿 🔔 关注我,不错过下一篇干货!我们下期再见!✨



