構造化配列
1. 学習内容
- ❶ 複数のデータ型を持つ構造化配列の作成
- ❷ フィールド名を指定してフィールドにアクセスする
- ❸ 属性形式のアクセス用の配列を記録する
- ❹ 構造化配列のソートとフィルタリング
2. 主要な概念
PYTHON
import numpy as np
# Define structured dtype
dt = np.dtype([('name', 'U10'), ('age', 'i4'), ('salary', 'f8')])
# Create array
employees = np.array([
('Alice', 30, 75000.0),
('Bob', 25, 62000.0),
('Charlie', 35, 85000.0),
('Diana', 28, 71000.0)
], dtype=dt)
# Access fields
print(employees['name']) # ['Alice' 'Bob' 'Charlie' 'Diana']
print(employees['salary']) # [75000. 62000. 85000. 71000.]
# Record array (attribute access)
emp_rec = np.rec.array(employees)
print(emp_rec.name) # ['Alice' 'Bob' 'Charlie' 'Diana']
print(emp_rec.salary) # [75000. 62000. 85000. 71000.]
# Filtering
print(employees[employees['salary'] > 70000]['name'])
# ['Alice' 'Charlie']
# Sorting
sorted_emp = np.sort(employees, order='salary')
print(sorted_emp['name']) # ['Bob' 'Diana' 'Alice' 'Charlie']
TEXT
> Output: Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.
(1) ▶ サンプル:構造化配列の作成とアクセス(難易度 ⭐)
PYTHON
import numpy as np
dt = np.dtype([('product', 'U15'), ('price', 'f8'), ('quantity', 'i4')])
inventory = np.array([
('Widget', 9.99, 100),
('Gadget', 24.99, 50),
('Doohickey', 4.99, 200),
('Thingamajig', 14.99, 75)
], dtype=dt)
print("Products:", inventory['product'])
print("Prices:", inventory['price'])
print("Total value:", np.sum(inventory['price'] * inventory['quantity']))
出力:
TEXT製品:['ウィジェット' 'ガジェット' 'ドゥーヒッキー' 'シンガマジグ'] 価格:[ 9.99 24.99 4.99 14.99] 合計金額:4396.0
(2) ▶ サンプル:構造化配列のフィルタリング(難易度 ⭐⭐)
PYTHON
import numpy as np
dt = np.dtype([('name', 'U15'), ('age', 'i4'), ('salary', 'f8')])
employees = np.array([
('Alice', 30, 75000), ('Bob', 25, 62000),
('Charlie', 35, 85000), ('Diana', 28, 71000),
('Eve', 45, 95000), ('Frank', 32, 78000)
], dtype=dt)
# Filter: salary > 70000 AND age < 40
mask = (employees['salary'] > 70000) & (employees['age'] < 40)
filtered = employees[mask]
print("Filtered:", filtered['name'])
# Average salary by age group
young = employees[employees['age'] < 30]
print("Young avg salary:", young['salary'].mean())
出力:
TEXTフィルタリング済み:['Alice' 'Charlie' 'Frank'] 若年層の平均給与:66500.0
(3) ▶ サンプル:構造化配列をフィールドごとにソートする(難易度 ⭐⭐)
PYTHON
import numpy as np
dt = np.dtype([('city', 'U15'), ('population', 'i4'), ('area', 'f8')])
cities = np.array([
('Tokyo', 13960000, 2194), ('Delhi', 16780000, 1484),
('Shanghai', 24870000, 6341), ('Mumbai', 12440000, 603),
('Beijing', 21540000, 16411)
], dtype=dt)
# Sort by population descending
by_pop = np.sort(cities, order='population')[::-1]
print("By population:", by_pop['city'])
# Sort by density (population / area)
density = cities['population'] / cities['area']
dense_idx = np.argsort(-density)
print("By density:", cities['city'][dense_idx])
出力:
TEXT人口順:['上海' '北京' 'デリー' '東京' 'ムンバイ'] 人口密度順:['ムンバイ' 'デリー' '東京' '上海' '北京']
Q 構造化配列とPandasは、それぞれどのような場合に使用すべきですか?
A 同種の演算に対してNumPyの処理速度やメモリ効率を必要とする場合は、構造化配列を使用してください。ラベル付け、グループ化、欠損値の処理など、より複雑なデータ分析を行う場合は、Pandasを使用してください。
Q 既存の構造化配列にフィールドを追加することはできますか?
A いいえ。構造化配列のデータ型(dtype)は固定されています。追加するフィールドを含む新しいデータ型を作成し、データをコピーしてください。便宜上、
np.lib.recfunctions.append_fields を使用してください。Q 構造化配列とrecarrayの違いは何ですか?
A recarray(レコード配列)では、フィールドアクセス(
emp['name'])に加えて、属性アクセス(emp.name)も可能です。処理速度は若干遅くなりますが、より便利です。❓ よくある質問
Q 最も重要なポイントは何か?
A NumPyの演算はベクトル化されているため、パフォーマンスを向上させるにはPythonのループは避けるべきだ。
Q さらに詳しく知りたい場合はどうすればよいですか?
A 詳細なリファレンスや高度なトピックについては、numpy.org の NumPy 公式ドキュメントをご覧ください。
Q これはNumPy 2.xでも動作しますか?
A はい。すべての例はNumPy 2.xと互換性があります。一部の古いAPI(np.random.seedなど)は引き続きサポートされていますが、最新の代替APIの使用をお勧めします。
📖 まとめ
- 構造化配列は、複合データ型を使用して、単一のndarrayに異なる型の要素を格納します
- フィールド名を指定してアクセスする:
arr['fieldname'] - レコード配列により、属性形式でのアクセスが可能になります:
arr.fieldname - ブールマスクと
np.sortを使用して、フィールド値によるフィルタリングおよび並べ替えを行う - 複雑な表形式のデータについては、PandasのDataFrameの利用を検討してください
📝 練習問題
-
初心者(難易度 ⭐):product(U20)、price(f8)、quantity(i4)というフィールドを持つ構造化配列を作成してください。5つの商品を追加してください。
-
中級(難易度 ⭐⭐):products配列から、価格が50より大きく、数量が10未満のアイテムを抽出してください。価格の降順で並べ替えてください。
-
上級(難易度 ⭐⭐⭐):
np.lib.recfunctionsを使用して、配列に「total_value」フィールド(価格 × 数量)を追加してください。計算結果を確認してください。