NumPy - 结构化数组的操作



在 NumPy 中操作结构化数组

在 NumPy 中操作结构化数组意味着根据您的需求修改、重新排列或处理这些数组中的数据。

结构化数组是特殊的数组,其中每个元素可以具有多个字段(例如姓名、年龄、身高),并且每个字段可以具有不同的数据类型(例如字符串、整数或浮点数)。

在 NumPy 中,您可以通过多种方式操作结构化数组:

  • 访问和修改字段
  • 添加新字段
  • 删除字段
  • 数组排序
  • 数组过滤
  • 数组合并
  • 数组重塑
  • 数组分割

访问和修改字段

您可以使用字段名称作为访问结构化数组中的特定字段。这类似于访问字典中的值的方式。例如,如果您有一个具有姓名、年龄和身高等字段的结构化数组,您可以访问年龄字段以检索数组中存储的所有年龄。

访问字段后,您还可以修改其值。例如,如果您想更新数组中某人的年龄,您可以通过直接为年龄字段中相应的元素赋值新值来实现。

示例

在下面的示例中,我们访问并修改结构化数组中的“年龄”字段。具体来说,我们将第一个元素(Alice)的年龄从 30 更新为 31,然后检索更新后的年龄:

import numpy as np

# Define the dtype with field names and data types
dtype = [('name', 'U10'), ('age', 'i4'), ('height', 'f4')]

# Create the structured array with some initial data
data = [('Alice', 30, 5.6), ('Bob', 25, 5.8), ('Charlie', 35, 5.9)]
structured_array = np.array(data, dtype=dtype)

# Accessing the 'age' field
ages = structured_array['age']
print("Ages before modification:", ages)

# Modifying the 'age' field - let's update Alice's age to 31
structured_array['age'][0] = 31

# Accessing the 'age' field again to see the changes
print("Ages after modification:", structured_array['age'])

以下是获得的输出:

Ages before modification: [30 25 35]
Ages after modification: [31 25 35]

向结构化数组添加新字段

要向现有结构化数组添加新字段,您需要创建一个包含附加字段的新数组并将现有数据复制过去。

当您的数据结构发生变化并需要附加信息时,此过程可能很有必要。

示例

在这个例子中,我们通过添加一个名为“Grade”的新字段来扩展现有的结构化数组。我们将现有数据复制到包含附加字段的新数组中,然后用相应的值填充新的“Grade”字段:

import numpy as np

# Existing structured array
students = np.array([(1, 'Alice', 25), (2, 'Bob', 23), (3, 'Charlie', 35)],
                    dtype=[('ID', 'i4'), ('Name', 'U10'), ('Age', 'i4')])

# Define a new dtype with an additional field 'Grade'
new_dtype = [('ID', 'i4'), ('Name', 'U10'), ('Age', 'i4'), ('Grade', 'f4')]

# Create a new structured array with the new dtype
students_with_grade = np.zeros(students.shape, dtype=new_dtype)

# Copy the old data
for field in students.dtype.names:
    students_with_grade[field] = students[field]

# Add data to the new 'Grade' field
students_with_grade['Grade'] = [85.5, 90.0, 88.0]

print(students_with_grade)

这将产生以下结果:

[(1, 'Alice', 25, 85.5) (2, 'Bob', 23, 90. ) (3, 'Charlie', 35, 88. )]

从结构化数组中删除字段

要删除字段,您必须创建一个具有修改后的dtype的新结构化数组,该数组排除了不需要的字段,然后将数据从原始数组复制到新数组。

示例

在下面的示例中,我们通过创建一个具有简化 dtype 的新数组来从现有结构化数组中删除“Age”字段。然后,我们将原始数组中的相关字段复制到新数组中:

import numpy as np

# Original structured array
students = np.array([(1, 'Alice', 25), (2, 'Bob', 23), (3, 'Charlie', 35)],
                    dtype=[('ID', 'i4'), ('Name', 'U10'), ('Age', 'i4')])

# Define a new dtype without the 'Age' field
reduced_dtype = [('ID', 'i4'), ('Name', 'U10')]

# Create a new structured array with the reduced dtype
students_without_age = np.zeros(students.shape, dtype=reduced_dtype)

# Copy the relevant fields
for field in students_without_age.dtype.names:
    students_without_age[field] = students[field]

# Verify the result
print(students_without_age)

以下是上述代码的输出:

[(1, 'Alice') (2, 'Bob') (3, 'Charlie')]

结构化数组排序

NumPy 中的结构化数组排序涉及根据一个或多个字段(列)对数组的元素(行)进行排序。

结构化数组可以具有不同数据类型的多个字段(例如,整数、浮点数、字符串),排序允许您以有意义的方式组织数据,例如按年龄、名称或任何其他属性排列记录。

示例

在下面的示例中,我们使用带有“order”参数的 np.sort() 函数根据“Age”字段对结构化数组进行排序。这会根据“Age”值按升序重新排列记录:

import numpy as np

# Original structured array
students = np.array([(1, 'Alice', 25), (2, 'Bob', 23), (3, 'Charlie', 35)],
                    dtype=[('ID', 'i4'), ('Name', 'U10'), ('Age', 'i4')])

# Sort by 'Age'
sorted_students = np.sort(students, order='Age')
print(sorted_students)

获得的输出如下所示:

[(2, 'Bob', 23) (1, 'Alice', 25) (3, 'Charlie', 35)]

过滤结构化数组中的数据

使用 NumPy 过滤结构化数组中的数据涉及选择满足特定条件的数据子集。

要过滤结构化数组,您可以使用布尔索引。这涉及根据应用于一个或多个字段的条件创建一个布尔掩码(一个包含 True 和 False 值的数组)。然后,您可以使用此掩码索引到原始数组并提取所需记录的子集。

示例

在这个例子中,我们使用布尔掩码来过滤结构化数组,只选择“Age”字段大于 25 的记录:

import numpy as np

# Original structured array
students = np.array([(1, 'Alice', 25), (2, 'Bob', 23), (3, 'Charlie', 30)],
                    dtype=[('ID', 'i4'), ('Name', 'U10'), ('Age', 'i4')])

# Create a boolean mask where Age > 25
mask = students['Age'] > 25

# Apply the mask to filter the array
filtered_students = students[mask]
print(filtered_students)

执行上述代码后,我们将得到以下输出:

[(3, 'Charlie', 30)]

合并结构化数组

NumPy 中的结构化数组合并用于沿单个轴(通常是行)合并具有相同 dtype 的数组。

在 NumPy 中,np.concatenate() 函数用于沿现有轴连接数组。对于结构化数组,这要求所有数组共享相同的 dtype。

示例

在下面的示例中,我们使用 np.concatenate() 函数将两个具有相同数据类型的结构化数组合并为一个数组:

import numpy as np

# Define two structured arrays with the same dtype
students1 = np.array([(1, 'Alice', 25), (2, 'Bob', 23)],
                     dtype=[('ID', 'i4'), ('Name', 'U10'), ('Age', 'i4')])
students2 = np.array([(3, 'Charlie', 30), (4, 'David', 28)],
                     dtype=[('ID', 'i4'), ('Name', 'U10'), ('Age', 'i4')])

# Concatenate the arrays
combined_students = np.concatenate((students1, students2))
print(combined_students)

产生的结果如下:

[(1, 'Alice', 25) (2, 'Bob', 23) (3, 'Charlie', 30) (4, 'David', 28)]

重塑结构化数组

NumPy 中的结构化数组重塑涉及在保留其数据结构的同时更改数组的形状。这意味着在重塑前后元素(行)的总数保持不变。

在 NumPy 中,np.reshape() 函数用于更改结构化数组的形状。

示例

在下面的示例中,我们使用 np.reshape() 函数将一维结构化数组重塑为二维数组:

import numpy as np

# Define a 1-D structured array
students = np.array([(1, 'Alice', 25), (2, 'Bob', 23), (3, 'Charlie', 30)],
                    dtype=[('ID', 'i4'), ('Name', 'U10'), ('Age', 'i4')])

# Reshape the array from 1-D to 2-D
reshaped_students = np.reshape(students, (3, 1))
print(reshaped_students)

这将数组从单行记录转换为列格式,同时保留如下输出所示的结构化数据:

[[(1, 'Alice', 25)]
 [(2, 'Bob', 23)][(3, 'Charlie', 30)]]

分割结构化数组

NumPy 中的结构化数组分割涉及根据某些条件或大小将单个结构化数组划分为多个数组。

在 NumPy 中,np.split() 函数用于沿指定的轴将数组分割成多个子数组。对于结构化数组,此函数要求数组沿元素可以均匀分布的轴进行分割。

示例

在这个例子中,我们使用 np.split() 函数将结构化数组分成两等份:

import numpy as np

# Define a structured array
students = np.array([(1, 'Alice', 25), (2, 'Bob', 23), (3, 'Charlie', 30), (4, 'David', 28)],
                    dtype=[('ID', 'i4'), ('Name', 'U10'), ('Age', 'i4')])

# Split the array into 2 equal parts
split_students = np.split(students, 2)
print(split_students[0])
print(split_students[1])

我们得到如下所示的输出:

[(1, 'Alice', 25) (2, 'Bob', 23)]
[(3, 'Charlie', 30) (4, 'David', 28)]
广告