構造化配列

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の使用をお勧めします。

📖 まとめ



📝 練習問題

  1. 初心者(難易度 ⭐):product(U20)、price(f8)、quantity(i4)というフィールドを持つ構造化配列を作成してください。5つの商品を追加してください。

  2. 中級(難易度 ⭐⭐):products配列から、価格が50より大きく、数量が10未満のアイテムを抽出してください。価格の降順で並べ替えてください。

  3. 上級(難易度 ⭐⭐⭐)np.lib.recfunctions を使用して、配列に「total_value」フィールド(価格 × 数量)を追加してください。計算結果を確認してください。

Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%