2
0

PythonでリストとNumPy配列に要素を挿入する方法の備忘録

Last updated at Posted at 2023-12-14

はじめに

Pythonにおいて、リストやNumPy配列に要素を挿入する方法は多岐にわたります。この記事では、これらの方法を理解しやすいように、具体的な例を通じて説明してみます。

がこの記事の google colab へのリンクです。

使い方としては、

  • リストは + でくっつけることができるが、numpy は配列同士の演算になるので、要素の結合にはならない。
  • リストは可変長なので、同じリストに新しい要素を追加できるが、numpy の配列は固定長なので新しい numpy 配列に追加になる。
  • リストはスライス a[i:i]=b のように、同じ場所を指定してそこに挿入ができるが、numpy だとできない。

初期データの設定

まず、操作に使用するリストとNumPy配列を定義します。

import numpy as np

a_list = [(1, 1), (2, 2), (3, 3)]
b_list = [(10, 10), (20, 20), (30, 30)]
a_np = np.array(a_list)
b_np = np.array(b_list)

ここでは、a_listb_list という2つのリスト、およびこれらに相当するNumPy配列 a_npb_np を作成しています。

リストへの挿入

スライスを使用する方法

a_slice = a_list.copy()
a_slice[1:1] = b_list
print("スライス:", a_slice)
# スライス: [(1, 1), (10, 10), (20, 20), (30, 30), (2, 2), (3, 3)]

スライスを使用する方法では、指定した位置に新しいリスト b_list の要素を挿入します。ここでは、a_list のインデックス1の位置に b_list を挿入しています。

a_slice[1:1] = b_list1:1 は、Pythonのスライス表記により、リスト a_slice のインデックス1の直前(インデックス1の位置)に、リスト b_list の要素を挿入することを指します。スライス表記 1:1 は、開始インデックスと終了インデックスが同じであるため、元のリストからは何も選択されません(つまり、空の範囲を示しています)。

具体的には、以下のように動作します:

  • a_slice[1:1] は、リスト a_sliceインデックス1の位置を指し、そこから何も選択しません(空のスライスを作成します)。
  • a_slice[1:1] = b_list は、その空のスライスの位置に b_list の要素を挿入します。

+ 演算子を使用する方法

a_plus = a_list[:1] + b_list + a_list[1:]
print("+ 演算子:", a_plus)
# + 演算子: [(1, 1), (10, 10), (20, 20), (30, 30), (2, 2), (3, 3)]

+ 演算子を使用すると、リストを分割し、その間に別のリストを挿入することができます。この方法も、a_list の指定された位置に b_list を挿入しています。

insert を使う方法

a_insert = a_list.copy()
a_insert.insert(1, b_list)
print("insert:", a_insert)
# insert: [(1, 1), [(10, 10), (20, 20), (30, 30)], (2, 2), (3, 3)]

insert メソッドを使用すると、リストの特定の位置に直接新しい要素を挿入できます。この例では、a_list のインデックス1に b_list を挿入しています。

NumPy配列への挿入

concatenate を使う

a_concat = np.concatenate((a_np[:1], b_np, a_np[1:]))
print("concatenate:", a_concat)
# concatenate: 
#[[ 1  1]
# [10 10]
# [20 20]
# [30 30]
# [ 2  2]
# [ 3  3]]

NumPyの concatenate 関数を使うと、複数の配列を結合して新しい配列を作成できます。この例では、a_np の指定された位置に b_np を挿入しています。

numpy.insert を使う

a_insert = np.insert(a_np, 1, b_np, axis=0)
print("np.insert:", a_insert)
# np.insert: 
#[[ 1  1]
# [10 10]
# [20 20]
# [30 30]
# [ 2  2]
# [ 3  3]]

NumPyの insert 関数を使うと、配列の特定の位置に新しい行または列を挿入できます。この例では、a_np のインデックス1に b_npの行を挿入しています。

サンプルコード全文

import numpy as np

# 初期データの設定
a_list = [(1, 1), (2, 2), (3, 3)]
b_list = [(10, 10), (20, 20), (30, 30)]
a_np = np.array(a_list)
b_np = np.array(b_list)

# 挿入位置
insert_index = 1

# リスト操作
def insert_into_list(a, b, index):
    # スライスを使用する方法
    a_slice = a.copy()
    a_slice[index:index] = b
    print("スライス:", a_slice)

    # + 演算子を使用する方法
    a_plus = a[:index] + b + a[index:]
    print("+ 演算子:", a_plus)

    # insert を使う方法
    a_insert = a.copy()
    a_insert.insert(index, b)
    print("insert:", a_insert)

insert_into_list(a_list, b_list, insert_index)

# NumPy配列操作
def insert_into_numpy(a, b, index):
    # concatenate を使う
    a_concat = np.concatenate((a[:index], b, a[index:]))
    print("concatenate:", a_concat)

    # numpy.insert を使う
    a_insert = np.insert(a, index, b, axis=0)
    print("np.insert:", a_insert)

insert_into_numpy(a_np, b_np, insert_index)

これを実行すると、

スライス: [(1, 1), (10, 10), (20, 20), (30, 30), (2, 2), (3, 3)]
+ 演算子: [(1, 1), (10, 10), (20, 20), (30, 30), (2, 2), (3, 3)]
insert: [(1, 1), [(10, 10), (20, 20), (30, 30)], (2, 2), (3, 3)]
concatenate: [[ 1  1]
 [10 10]
 [20 20]
 [30 30]
 [ 2  2]
 [ 3  3]]
np.insert: [[ 1  1]
 [10 10]
 [20 20]
 [30 30]
 [ 2  2]
 [ 3  3]]

という出力になります。

その他のオペレーション

map関数を用いた掛け算

map関数を使うことで、関数にするほどのではない演算を短くかけます。list(map( という使い方をすることで、map で生成される要素を list で強制的に配列の全要素に作用させることになります。具体例でみてみましょう。

一次元のリストの場合

my_list = [1, 2, 3, 4, 5]
factor = 2
multiplied_list = list(map(lambda x: x * factor, my_list))
# multiplied_list
# [2, 4, 6, 8, 10]

2次元のリストの場合

各タプルの第一要素に2を掛け、第二要素に3を掛けるとします。
以下のようにmap関数を使用できます。

my_list = [(1, 2), (3, 4), (5, 6)]
multiplied_list = list(map(lambda x: (x[0] * 2, x[1] * 3), my_list))
# multiplied_list
# [(2, 6), (6, 12), (10, 18)]

map関数の使い方の補足

map関数は、指定された関数をリスト(または他のイテラブル)の各要素に適用し、結果をmapオブジェクトとして返します。mapオブジェクトはイテレータであり、すべての結果を一度にメモリに格納するのではなく、要求されたときにそれぞれの結果を生成します。

list関数mapの外側に使用する理由は、mapオブジェクトをリストに変換して、すべての結果を一度に取得するためです。listを使用しない場合、mapオブジェクトを直接イテレートするか、next関数を使用して各要素を個別に取り出す必要があります。

例えば、以下のように書くことができます:

# mapオブジェクトを直接使用
my_list = [(1, 2), (3, 4), (5, 6)]
multiplied_map = map(lambda x: (x[0] * 2, x[1] * 3), my_list)

# mapオブジェクトから要素を一つずつ取り出す
for item in multiplied_map:
    print(item)

この方法は、すべての結果を一度にリストとして格納する必要がない場合に便利ですが、結果を再利用したい場合や、結果の全体像が必要な場合はlist関数を使用してリストに変換するのが良いでしょう。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0