NumPy - 記錄陣列



NumPy中的記錄陣列

記錄陣列類似於結構化陣列,但具有一個附加功能:它們允許您使用屬性樣式(點表示法)和索引樣式(字典樣式)訪問來訪問欄位作為屬性。

這可以使程式碼更易於閱讀和編寫,尤其是在處理複雜資料結構時。

建立記錄陣列

我們可以透過多種方式建立記錄陣列,它們是:

  • 透過轉換現有結構化陣列
  • 直接定義記錄陣列
  • 使用 np.recarray 建構函式

將結構化陣列轉換為記錄陣列

建立記錄陣列最簡單的方法之一是使用 view 方法轉換現有的結構化陣列。這種方法允許您在獲得屬性訪問便利性的同時保持資料的結構。

示例

在下面的示例中,我們將 NumPy 中的結構化陣列轉換為記錄陣列:

import numpy as np

# Create a structured array
structured_array = np.array([('Alice', 25, 5.5), ('Bob', 30, 6.0)], dtype=[('name', 'U10'), ('age', 'i4'), ('height', 'f4')])

# Convert the structured array to a record array
record_array = structured_array.view(np.recarray)

# Access fields as attributes
print(record_array.name)  
print(record_array.age)  

獲得的輸出如下:

['Alice' 'Bob']
[25 30]

直接建立記錄陣列

建立記錄陣列的另一種方法是使用 **np.rec.array()** 函式直接定義它。此方法允許您從頭開始建立記錄陣列,同時指定資料和結構。

示例

在下面的示例中,我們直接在 NumPy 中建立記錄陣列,這允許我們使用點表示法訪問欄位作為屬性:

import numpy as np 

# Directly create a record array
record_array_direct = np.rec.array([('Charlie', 35, 5.8), ('David', 40, 6.2)], dtype=[('name', 'U10'), ('age', 'i4'), ('height', 'f4')])

# Access fields as attributes
print(record_array_direct.name)   
print(record_array_direct.height) 

這將產生以下結果:

['Charlie' 'David']
[5.8 6.2]

使用 np.recarray 建構函式

您還可以使用 np.recarray 建構函式建立記錄陣列。此方法不太常見,但在特定用例中提供額外的靈活性。

示例

在這個例子中,我們使用 np.recarray 建構函式建立一個記錄陣列,為其分配資料,然後訪問欄位 **name** 和 **age** 作為屬性:

import numpy as np

# Define a record array using np.recarray
record_array_custom = np.recarray((2,), dtype=[('name', 'U10'), ('age', 'i4'), ('height', 'f4')])

# Assign data to the record array
record_array_custom[0] = ('Eve', 28, 5.7)
record_array_custom[1] = ('Frank', 33, 6.1)

# Access fields as attributes
print(record_array_custom.name)   
print(record_array_custom.age)   

以上程式碼的輸出如下:

['Eve' 'Frank']
[28 33]

訪問記錄陣列的欄位

建立記錄陣列後,您可以將其欄位(即結構化資料的列)作為屬性訪問,這簡化了資料操作和查詢。

訪問記錄陣列欄位最常用的方法是使用 **點 (.)** 表示法。記錄陣列的每個欄位都成為可以直接訪問的屬性,類似於您在 Python 中訪問物件屬性的方式。

示例:使用屬性表示法訪問欄位

在下面的示例中,我們建立一個具有欄位 **name**、**age** 和 **height** 的記錄陣列,然後將每個欄位作為記錄陣列的屬性訪問:

import numpy as np

# Create a record array
record_array = np.rec.array([('Alice', 25, 5.5), ('Bob', 30, 6.0)], dtype=[('name', 'U10'), ('age', 'i4'), ('height', 'f4')])

# Accessing the 'name' field
print(record_array.name)  

# Accessing the 'age' field
print(record_array.age)   

# Accessing the 'height' field
print(record_array.height) 

獲得的輸出如下:

['Alice' 'Bob']
[25 30]
[5.5 6. ]

示例:同時訪問多個欄位

除了訪問單個欄位外,您還可以一次訪問多個欄位。但是,與結構化陣列不同,記錄陣列不支援使用屬性表示法直接同時訪問欄位。

如果您想一次檢索多個欄位,則需要像下面的示例中所示那樣恢復到傳統的索引方法:

import numpy as np

# Create a record array
record_array = np.rec.array([('Alice', 25, 5.5), ('Bob', 30, 6.0)], dtype=[('name', 'U10'), ('age', 'i4'), ('height', 'f4')])

# Access multiple fields using indexing
multiple_fields = record_array[['name', 'height']]
print(multiple_fields)

執行上述程式碼後,我們得到以下輸出:

[('Alice', 5.5) ('Bob', 6. )]

修改記錄陣列的欄位

修改 NumPy 記錄陣列中的欄位允許您更新或更改結構化資料集中的特定列(欄位)中的資料。記錄陣列提供了一種使用 **屬性樣式** 訪問來訪問和修改欄位的方法。

例如,您可以透過點 (.) 表示法訪問欄位,然後應用所需的運算或賦值來修改記錄陣列中各個欄位的值。

要向記錄陣列新增新欄位,您可以結合使用 np.concatenat() 函式(或類似函式)來建立一個包含附加欄位的新記錄陣列。

示例:更新欄位

在下面的示例中,我們建立一個具有欄位“name”、“age”和“height”的記錄陣列。然後我們更改特定記錄的“age”和“height”:

import numpy as np

# Step 1: Define the initial record array with fields 'name', 'age', and 'height'
dtype = [('name', 'S20'), ('age', 'i1'), ('height', 'f4')]
data = [('Alice', 30, 5.5), ('Bob', 25, 6.0), ('Charlie', 35, 5.8)]
record_array = np.array(data, dtype=dtype)

print("Original Record Array:")
print(record_array)

# Step 2: Update the fields for specific records
# Update 'age' and 'height' for 'Bob'
record_array[record_array['name'] == b'Bob']['age'] = 26
record_array[record_array['name'] == b'Bob']['height'] = 6.1

# Update 'age' for 'Charlie'
record_array[record_array['name'] == b'Charlie']['age'] = 36

print("\nUpdated Record Array:")
print(record_array)

產生的結果如下:

Original Record Array:
[(b'Alice', 30, 5.5) (b'Bob', 25, 6. ) (b'Charlie', 35, 5.8)]

Updated Record Array:
[(b'Alice', 30, 5.5) (b'Bob', 25, 6. ) (b'Charlie', 35, 5.8)]

示例:新增新欄位

在這個例子中,我們首先定義一個只包含“name”和“age”欄位的記錄陣列。然後我們建立一個包含額外“height”欄位的新記錄陣列:

import numpy as np

# Step 1: Define the initial record array with fields 'name' and 'age'
dtype = [('name', 'S20'), ('age', 'i1')]
data = [('Alice', 30), ('Bob', 25), ('Charlie', 35)]
record_array = np.array(data, dtype=dtype)

print("Original Record Array:")
print(record_array)

# Step 2: Define a new dtype that includes the new field 'height'
new_dtype = [('name', 'S20'), ('age', 'i1'), ('height', 'f4')]

# Step 3: Create a new record array with the new dtype, initialized with zeros or default values
new_record_array = np.zeros(record_array.shape, dtype=new_dtype)

# Step 4: Copy existing data into the new record array
for field in ['name', 'age']:
    new_record_array[field] = record_array[field]

# Optionally, set default values for the new field 'height'
new_record_array['height'] = 0.0

print("\nRecord Array with New Field:")
print(new_record_array)

我們得到如下所示的輸出:

Original Record Array:
[(b'Alice', 30) (b'Bob', 25) (b'Charlie', 35)]

Record Array with New Field:
[(b'Alice', 30, 0.) (b'Bob', 25, 0.) (b'Charlie', 35, 0.)]

組合記錄陣列

在 NumPy 中組合記錄陣列是指將多個記錄數組合並或連線成單個記錄陣列。當您需要組合資料集或使用其他行擴充套件現有資料集時,此過程非常有用。

以下是組合記錄陣列的方法:

  • **連線:**沿現有軸(通常沿行)組合記錄陣列。
  • **堆疊:**沿新軸堆疊記錄陣列,這對於新增新維度很有用。

示例:連線記錄陣列

在下面的示例中,我們建立兩個記錄陣列,然後沿行將它們連線起來以形成一個組合的單個記錄陣列:

import numpy as np

# Define two record arrays with fields 'name', 'age', and 'height'
dtype = [('name', 'U10'), ('age', 'i4'), ('height', 'f4')]
data1 = [('Alice', 25, 5.5), ('Bob', 30, 6.0)]
data2 = [('Charlie', 35, 5.8), ('David', 40, 5.9)]

# Create record arrays
record_array1 = np.array(data1, dtype=dtype).view(np.recarray)
record_array2 = np.array(data2, dtype=dtype).view(np.recarray)

# Concatenate the record arrays along the rows (axis 0)
combined_record_array = np.concatenate((record_array1, record_array2))

print("Combined record array:")
print(combined_record_array)

獲得的輸出如下:

Combined record array:
[('Alice', 25, 5.5) ('Bob', 30, 6. ) ('Charlie', 35, 5.8)
 ('David', 40, 5.9)]

示例:堆疊記錄陣列

在下面的示例中,我們建立兩個記錄陣列,然後沿新軸將它們堆疊起來以形成一個 3D 記錄陣列:

import numpy as np

# Define two record arrays with fields 'name', 'age', and 'height'
dtype = [('name', 'U10'), ('age', 'i4'), ('height', 'f4')]
data1 = [('Alice', 25, 5.5), ('Bob', 30, 6.0)]
data2 = [('Charlie', 35, 5.8), ('David', 40, 5.9)]

# Create record arrays
record_array1 = np.array(data1, dtype=dtype).view(np.recarray)
record_array2 = np.array(data2, dtype=dtype).view(np.recarray)

# Stack the record arrays along a new axis
stacked_record_array = np.stack((record_array1, record_array2), axis=0)

print("Stacked record array:")
print(stacked_record_array)

這將產生以下結果:

Stacked record array:
[[('Alice', 25, 5.5) ('Bob', 30, 6. )]
 [('Charlie', 35, 5.8) ('David', 40, 5.9)]]

過濾記錄陣列

過濾記錄陣列是指根據條件或條件集從記錄陣列中選擇特定的行或元素。

此過程用於提取滿足特定條件的資料子集,這有助於我們進行更集中的分析和操作。

示例

在這個例子中,我們建立一個布林掩碼來過濾記錄陣列中“age”大於“30”的記錄:

import numpy as np

# Define a record array with fields 'name', 'age', and 'height'
dtype = [('name', 'U10'), ('age', 'i4'), ('height', 'f4')]
data = [('Alice', 25, 5.5), ('Bob', 30, 6.0), ('Charlie', 35, 5.8), ('David', 40, 5.9)]
record_array = np.array(data, dtype=dtype).view(np.recarray)

# Create a Boolean mask for ages greater than 30
mask = record_array.age > 30

# Apply the mask to filter the record array
filtered_record_array = record_array[mask]

print("Filtered record array (ages > 30):")
print(filtered_record_array)

以上程式碼的輸出如下:

Filtered record array (ages > 30):
[('Charlie', 35, 5.8) ('David', 40, 5.9)]
廣告