• 日本語
    • English (英語)
Avinton JapanAvinton JapanAvinton JapanAvinton Japan
  • サービス
    • Avinton Data Platform
    • エッジAIカメラ
      • 自動車ナンバープレート自動認識システム
    • プライベートクラウド
    • AIサービス開発
    • AIカメラ/画像解析無料体験版
  • 最新情報
    • ニュースリリース&イベント情報
    • 技術ブログ&インタビュー
  • アカデミー
    • Avintonアカデミー
    • Academy on Campus
    • Academy with Platform
  • 採用情報
    • Avintonジャパン 採用ページ
    • 求人一覧
    • よくある質問
    • 新卒採用
  • 企業情報
    • 会社概要
    • 代表からご挨拶
    • SDGsへの貢献
  • お問い合わせ

【Python入門】Python Numpy チュートリアル

  • ルーティング
  • データベースの命名規則
  • 三目並べ – 2.〇×を交互にゲーム盤に入るようにしよう
  • 三目並べ – 3.勝敗がつくようにしよう
  • クリーンコード(Clean Code)
  • 三目並べ – 4.「スタート」「リセット」ボタンをつけよう
  • 三目並べ – 5.先攻後攻を決めて、コンピュータ対戦にしよう(前編)
  • インフラストラクチャー(サーバー、コンポーネント、RAID)
  • 機械学習入門者向け Support Vector Machine (SVM) に触れてみる
  • YOLOv8を用いた物体検出
  • 正規表現とパイプ
  • 機械学習エンジニアに必要なスキル
  • 軽量版Kubernetesディストリビューション – k0s クラスターの構築
  • ファイル操作コマンド
  • グループとユーザー
  • 困った時に使うコマンド
  • 一般グループのユーザーとグループ
  • プライバシーポリシー
  • 三目並べ – 6.先攻後攻を決めて、コンピュータ対戦にしよう(後編)
  • フロントエンド開発のための環境構築
  • ファイル検索コマンド
  • 質問
  • 仮想化環境のディスク容量を拡張する
  • ユーザー権限とアクセス権
  • データ分析基礎 – Part1
  • 三目並べ – 0.導入
  • テキスト処理
  • データベースへのデータロード
  • 機械学習概要1
  • 機械学習入門者向け Naive Bayes(単純ベイズ)アルゴリズムに触れてみる
  • ファイル管理
  • SSHを使用してホストOSからゲストOSに接続する
  • 機械学習入門者向け ChainerRLでブロック崩しの学習
  • 機械学習入門者向け ランダムフォレストによる Kaggle Titanic生存者予測
  • 機械学習概要2
  • データ分析基礎 – Part 2
  • 機械学習入門者向け 分類と回帰の違いをプログラムを書いて学ぼう
  • フロントエンドのWeb開発について
  • ダイナミックルーティング
  • 三目並べ – 1.ゲーム盤を作ろう
  • 【Python入門】Python Numpy チュートリアル
  • Amazon EC2 インスタンスの初期設定をしよう
  • AmazonEC2とVPCでネットワークとサーバーを構築しよう
  • Apache NiFi Exercise
  • Apache NiFi データパイプライン基礎
  • Apache NiFiの環境設定
  • Apache Spark 基礎
  • Apache SparkとApache Zeppelinの概要と環境構築
  • Apache Superset maptoolの使い方
  • Apache Superset 基礎
  • Apache Superset 概要と環境構築
  • Apache Zeppelin 基本機能
  • APIのデモンストレーション
  • Avinton Academy コンテンツガイド
  • AWS CLIをインストールしてコマンド操作しよう
  • AWS CLIを使ってEC2のファイルをS3へアップロードしよう
  • AWS Route 53を使って独自ドメインのWebページを表示させてみよう
  • AWSアカウントの作成と必ずやるべきセキュリティ対策
  • AWSのEC2インスタンスでWordPressブログを公開してみよう
  • AWS入門者向け 初心者が最初に理解すべきEC2とVPCの基本的な用語解説
  • CCNA
  • Certbotを使ってSSL証明書を発行し、HTTP通信を暗号化しよう
  • CISCO 1800ルータセットアップ
  • CSV import & export – Node.js, mySQL – 1
  • CSV import & export – Node.js, mySQL – 2
  • Docker Compose(Nginx + Flask + MySQL)演習
  • Docker Engineのubuntu上へのinstall
  • Docker 概要とセットアップ
  • Docker, Kubernetesの学び方について
  • Dockerコンテナイメージの最適化/ベストプラクティス
  • DockerとApacheを使ってWebサーバーを構築しよう
  • EC2からS3へ自動でぽいぽいアップロードするスクリプトの作成
  • ESP32-CAMのサンプルアプリケーションを実行する
  • 01 – Sparkfun Inventor’s Kit の準備
  • 02 – Sparkfun Inventor’s KitでLチカ
  • 03 ポテンショメータでLEDの点滅間隔をアナログ入力する
  • 04 フォトレジスタで明るさに反応するシステムをつくる
  • 05 LCDに文字列を表示する
  • 06 – BME280とLCDを組み合わせて温度計をつくる
  • ESP32とArduino IDE/PlatfromIOでHello Worldアプリケーションの実行
  • ESP32と超音波センサー HC-SR04 で物体の距離を計測する
  • ESXi – Switchの追加とVLAN
  • ESXi – VyOS
  • ESXi – 小規模ネットワーク 構築
  • Gitとは
  • VS CodeでGitHub Copilotを設定する
  • VSCode リモート開発環境
  • GNS3のセットアップ
  • Kubernetesクラスター上へのOpenVINOモデルサーバーを使用したサンプルアプリケーションのデプロイ
  • Linuxとは
  • NAT
  • NodeJSでWebアプリケーション開発 – React編
  • NodeJSでWebアプリケーション開発 – React編
  • NodeJSでWebアプリケーション開発 – React編
  • NodeJSでWebアプリケーション開発 – Socket.IO編
  • NVIDIA Cumulus VX + GNS3でBGPネットワークのシミュレーション
  • OpenCVのテストプログラム
  • PacketTracerのセットアップ
  • Pandasによる構造化データ分析
  • PCからルータ、スイッチへのSSH接続設定
  • PostGIS exercise
  • PostgreSQL – Python – Apache – Bootstrap
  • MySQLとMySQL Workbench のセットアップ
  • PostgreSQL Setup
  • PostgreSQL – インデックスを利用したパフォーマンス改善方法
  • PostgreSQL – パーティショニングを利用したパフォーマンス改善方法
  • PostgreSQLによるデータ分析
  • postgreSQLへのshp fileのimport
  • Python2.7とOpenCVのインストール
  • Python3.8 と OpenCV のインストール (Ubuntu20.04LTS)
  • Pythonでデータベースを操作する
  • Pythonで画像を分類するプログラムを作成する
  • Pythonによるマルチスレッドプログラミング実践
  • Raspberry Pi 4B のセットアップ
  • Raspberry PiとBME280を使用して温度と湿度、気圧を読み取る
  • REDIS
  • Redux基礎 – 主要な概念と用語
  • Ruby on Rails を MySQLでセットアップ
  • Ruby on Railsによる簡単なウェブアプリケーション
  • SampleアプリケーションのKubernetes上へのデプロイ
  • Scala 基礎
  • scikit-learnとは
  • Spark SQL エクササイズ
  • SparkMLによるKaggle Titanic生存者予測
  • SparkMLによる住宅価格予測
  • SQL 便利な関数
  • Ubuntuの基本設定
  • uhubctlでUSBデバイスのオンオフをコントロール
  • Terraform入門 2 – Terraformのstate管理
  • Terraform入門 1 – TerraformでAWS上にEC2インスタンスを作成する
  • Virtualisation and Container (仮想化とコンテナ) – Ansible, Docker and Kubernetes
  • viエディタ
  • VLAN
  • VMware ESXi サーバー構築
  • Webアプリ開発に欠かせないGoogle Chrome DevToolsの基本
  • Windows Server 2012 R2 Hyper-V
  • YOLOv5を用いた物体検出
Home Avintonアカデミー 【Python入門】Python Numpy チュートリアル
Python Logo
Numpy logo

※このチュートリアルは2018年時点のスタンフォード大学のPython Numpy Tutorialを翻訳したものです。
※最新のチュートリアルはこちらからご確認ください。

Python Numpy チュートリアル

Pythonは優秀な汎用プログラミング言語ではありますが、numpy, scipy, matploblibといったライブラリ使用することで、データ・情報処理の分野でも重宝される存在です。

※Matlabをすでに使ったことがある方は numpy for Matlab users もご参考ください。

目次:

  • Python
    — 基本データ型
    — コンテナ
    — リスト
    — 辞書
    — セット
    — タプル
    — 関数
    — クラス
  • Numpy
    — 配列
    — 配列のインデックス参照
    — データ型
    — 配列の演算
    — ブロードキャスト
  • SciPy
    — 画像の操作
    — 点と点の距離
  • Matplotlib
    — プロット
    — サブプロット
    — 画像の表示

Python

Pythonは高水準な、動的型付けを行うマルチパラダイムプログラミング言語です。

Pythonはとても読みやすく、少ない行数でとても強力なプログラムを書くことができるため、「動作する擬似コード」と形容されることもあります。

例えば、以下はいわゆるクイックソートのアルゴリズムをPythonで書いたものです。

1
2
3
4
5
6
7
8
9
10
11
def quicksort(arr):
    if len(arr) <= 1:
        return arr
    pivot = arr[len(arr) // 2]
    left = [x for x in arr if x < pivot]
    middle = [x for x in arr if x == pivot]
    right = [x for x in arr if x > pivot]
    return quicksort(left) + middle + quicksort(right)
 
print(quicksort([3,6,8,10,1,2,1]))
# "[1, 1, 2, 3, 6, 8, 10]" と表示

Pythonのバージョン

現在よく使われるpythonのバージョンは2系と3系の二種類あり、2系は2.7、3系は3.5ないしは3.6がよく使われます。

面倒なことに、3系のpythonのコードは2系で動かず、逆もまた然りです。

今回のチュートリアルでは、python3.5を用います。

現在のPythonのバージョンは、ターミナルでpython --versionを実行することで確認できます。

また、システムによっては python と打つとpython2.7、 python3 と打つとpython3系が起動する場合があります。

基本データ型

たいていのプログラミング言語と同じように、Pythonにはinteger型、float型、boolean型、string型などの基本的なデータ型が用意されています。

動作も他の言語と似ています。

数値: integer型(整数)とfloat型(小数)に分かれます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
x = 3
 
print(type(x)) # "<class 'int'>"と表示
 
print(x) # "3"と表示
 
print(x + 1) # 足し算; "4"と表示
 
print(x - 1) # 引き算; "2"と表示
 
print(x * 2) # 掛け算; "6"と表示
 
print(x ** 2) # 累乗; "9"と表示
 
x += 1
 
print(x) # "4"と表示
 
x *= 2
 
print(x) # "8"と表示
 
y = 2.5
 
print(type(y)) # "<class 'float'>"と表示
 
print(y, y + 1, y * 2, y ** 2) # "2.5 3.5 5.0 6.25"と表示

多くのプログラミング言語とは異なり、Pythonはインクリメント演算子(x++)やデクリメント演算子(x--)には対応していません。

Pythonでは複素数も扱うことが可能です。

詳しくはこちらのドキュメントをご覧ください。

boolean型(ブール型): Pythonは通常の論理演算子にはすべて対応していますが、記号(&&や||など)より英単語を使う方が一般的です。

1
2
3
4
5
6
7
8
9
10
11
12
t = True
f = False
 
print(type(t)) # "<class 'bool'>"と表示
 
print(t and f) # 論理AND; "False"と表示
 
print(t or f) # 論理OR; "True"と表示
 
print(not t) # 論理NOT; "False"と表示
 
print(t != f) # 論理XOR; "True"と表示

String型(文字列): Pythonは文字列にもしっかり対応しています。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
hello = 'hello' # 文字列はシングル引用符で表示
world = "world" # もしくはダブル引用符で表示。どちらでも構わない
 
print(hello) # "hello"と表示
 
print(len(hello)) # 文字列の長さ; "5"と表示
 
hw = hello + ' ' + world # 文字列結合(もしくは連結)
 
print(hw) # "hello world"と表示
 
hw12 = '%s %s %d' % (hello, world, 12) # C言語のsprintfに似た文字列フォーマット
 
print(hw12) # "hello world 12"と表示

文字列には便利なメソッドが多数用意されています。

以下はその一例です。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
s = "hello"
 
print(s.capitalize()) # 先頭の文字を大文字にする; "Hello"と表示
 
print(s.upper()) # 文字列全体を大文字にする; "HELLO"と表示
 
print(s.rjust(7)) # 右揃えで、指定した文字数になるように空白を加える; " hello"と表示
 
print(s.center(7)) # 中央揃えで、指定した文字数になるように空白を加える; " hello "と表示
 
print(s.replace('l', '(ell)')) # 指定した文字列をすべて置換;
# "he(ell)(ell)o"と表示
 
print(' world '.strip()) # 先頭と末尾から空白を削除; "world"と表示

文字列メソッドについて、詳しくはこちらのドキュメントをご覧ください。

コンテナ

Pythonでは組み込みのコンテナ型としてlist型(リスト)、dictionary型(辞書)、set型(セット)、tuple型(タプル)が用意されています。

リスト

いわゆる配列をPythonで表す際にリストを使います。

しかし、pythonのリストはリサイズが可能で、また構成する各要素のデータ型が異なっていても成り立ちます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
xs = [3, 1, 2] # リストを作成
 
print(xs, xs[2]) # "[3, 1, 2] 2"と表示
 
print(xs[-1]) # 負の値ではリストの末尾から数える; "2"と表示
 
xs[2] = 'foo' # リストは異なったデータ型で構成できる
 
print(xs) # "[3, 1, 'foo']"と表示
 
xs.append('bar') # 要素をリストの末尾に追加
 
print(xs) # "[3, 1, 'foo', 'bar']"と表示
 
x = xs.pop() # リストの末尾の要素を削除し、引数として返す
 
print(x, xs) # "bar [3, 1, 'foo']"と表示

リストについて、詳しくはこちらのドキュメントをご覧ください。

スライス: リストの要素を一つずつではなく、部分的に取り出すことができます。

これをスライスと呼びます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
nums = list(range(5)) # rangeは連続した数字を作り出す組み込み関数
 
print(nums) # "[0, 1, 2, 3, 4]"表示
 
print(nums[2:4]) # インデックス2から4(4は含めない)のリストを取得; "[2, 3]"と表示
 
print(nums[2:]) # インデックス2から終わりまでのリストを取得; "[2, 3, 4]"と表示
 
print(nums[:2]) # 初めからインデックス2(2は含めない)までのリストを取得; "[0, 1]"と表示
 
print(nums[:]) # リストすべてを取得; "[0, 1, 2, 3, 4]"と表示
 
print(nums[:-1]) # スライスには負の値も使用できる; "[0, 1, 2, 3]"と表示
 
nums[2:4] = [8, 9] # スライスで取り出した部分に新しいリストを割り当てる
 
print(nums) # "[0, 1, 8, 9, 4]"と表示

スライスに関しては、Numpyの配列の章で再度扱います。

ループ: 以下のように、リスト内の要素をループ処理することができます。

1
2
3
4
5
animals = ['cat', 'dog', 'monkey']
 
for animal in animals:
    print(animal)
    # "cat", "dog", "monkey"をそれぞれ別の行で表示

ループ内でそれぞれの要素のインデックスも取り出したい場合は、組み込み関数enumerateを使います。

1
2
3
4
5
animals = ['cat', 'dog', 'monkey']
 
for idx, animal in enumerate(animals):
    print('#%d: %s' % (idx + 1, animal))
    # "#1: cat", "#2: dog", "#3: monkey"をそれぞれ別の行で表示

リスト内包表記: プログラミングでは、リストの中身を変換したいことがよくあります。

以下はその一例として、平方数を求めています。

1
2
3
4
5
6
nums = [0, 1, 2, 3, 4]
squares = []
for x in nums:
    squares.append(x ** 2)
 
print(squares) # "[0, 1, 4, 9, 16]"と表示

このコードはリスト内包表記を使うことで簡単に表すことができます。

1
2
3
4
nums = [0, 1, 2, 3, 4]
squares = [x ** 2 for x in nums]
 
print(squares) # "[0, 1, 4, 9, 16]"と表示

リスト内包表記は条件式にも対応しています。

1
2
3
4
nums = [0, 1, 2, 3, 4]
even_squares = [x ** 2 for x in nums if x % 2 == 0]
 
print(even_squares) # "[0, 4, 16]"と表示

辞書

辞書は、JavaのMapやJavascriptのObjectに似たもので、(キー, 値)のペアを持ちます。

以下のように使用します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
d = {'cat': 'cute', 'dog': 'furry'} # データと共に、新しい辞書を作成
 
print(d['cat']) # キーに対応する値を取り出す; "cute"と表示
 
print('cat' in d) # 辞書が、与えられたキーを持つかどうかを確認; "True"と表示
 
d['fish'] = 'wet' # 辞書に要素を追加
 
print(d['fish']) # "wet"と表示
 
print(d['monkey']) # KeyError: 'monkey'はdの中に存在しない
 
print(d.get('monkey', 'N/A')) # キーが存在しなければ"N/A"(指定しなければNone)を表示; "N/A"と表示
 
print(d.get('fish', 'N/A')) # キーが存在すれば対応する値を表示; "wet"と表示
 
del d['fish'] # 辞書から要素を削除
 
print(d.get('fish', 'N/A')) # "fish" は削除されている; "N/A"と表示

辞書について、詳しくはこちらのドキュメントをご覧ください。

ループ: 辞書の場合、以下のようにキーに対してループ処理が行われます。

1
2
3
4
5
d = {'person': 2, 'cat': 4, 'spider': 8}
for animal in d:
    legs = d[animal]
    print('A %s has %d legs' % (animal, legs))
    # "A person has 2 legs", "A cat has 4 legs", "A spider has 8 legs"と表示

キーとそれに対応した値の両方を取り出したい場合は、itemsメソッドを使用します。

1
2
3
4
5
d = {'person': 2, 'cat': 4, 'spider': 8}
 
for animal, legs in d.items():
    print('A %s has %d legs' % (animal, legs))
    # "A person has 2 legs", "A cat has 4 legs", "A spider has 8 legs"と表示

辞書内包表記: リスト内包表記と似たようにして、簡単に新たな辞書を作ることができます。

1
2
3
4
nums = [0, 1, 2, 3, 4]
even_num_to_square = {x: x ** 2 for x in nums if x % 2 == 0}
 
print(even_num_to_square) # "{0: 0, 2: 4, 4: 16}"と表示

セット

セット内の要素は順序がなく、また同じ要素が重複することはできません。

以下のように使用します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
animals = {'cat', 'dog'}
 
print('cat' in animals) # 要素がセット内にあるかどうかを確認する; "True"と表示
 
print('fish' in animals) # "False"と表示
 
animals.add('fish') # セットに要素を追加
 
print('fish' in animals) # "True"と表示
 
print(len(animals)) # セット内の要素の数; "3"と表示
 
animals.add('cat') # すでにセット内にある要素は追加しても何も変わらない
 
print(len(animals)) # "3"と表示
 
animals.remove('cat') # セットから要素を削除
 
print(len(animals)) # "2"と表示

セットについて、詳しくはこちらのドキュメントをご覧ください。

ループ: リストでのループ処理と同様です。

しかしセットには順序がないため、ループ処理の際どの順番で要素が取り出されるかは分かりません。

1
2
3
4
5
animals = {'cat', 'dog', 'fish'}
 
for idx, animal in enumerate(animals):
    print('#%d: %s' % (idx + 1, animal))
    # "#1: fish", "#2: dog", "#3: cat"と表示(順序は実行のたびに変わります)

セット内包表記: リストや辞書と同様に、簡単に新たなセットを作ることができます。

1
2
3
4
5
from math import sqrt
 
nums = {int(sqrt(x)) for x in range(30)}
 
print(nums) # "{0, 1, 2, 3, 4, 5}"と表示

タプル

タプルは追加・削除・変更などできず、順序があります。

多くの点でリストと似ていますが、リストと異なる点として、辞書のキーやセットの要素としても用いることができます。

以下にいくつか例を挙げます。

1
2
3
4
5
6
7
8
d = {(x, x + 1): x for x in range(10)} # タプルをキーとして用いた辞書を作成
t = (5, 6) # タプルを作成
 
print(type(t)) # "<class 'tuple'>"と表示
 
print(d[t]) # "5"と表示
 
print(d[(1, 2)]) # "1"と表示

タプルについて、詳しくはこちらのドキュメントをご覧ください。

関数

Pythonの関数はdefを用いて定義します。

1
2
3
4
5
6
7
8
9
10
11
def sign(x):
    if x > 0:
        return 'positive'
    elif x < 0:
        return 'negative'
    else:
        return 'zero'
 
for x in [-1, 0, 1]:
    print(sign(x))
# "negative", "zero", "positive"と表示

以下のように、引数の値をデフォルトで指定することも可能です。

1
2
3
4
5
6
7
8
9
def hello(name, loud=False):
    if loud:
        print('HELLO, %s!' % name.upper())
    else:
        print('Hello, %s' % name)
 
hello('Bob') # "Hello, Bob"と表示
 
hello('Fred', loud=True) # "HELLO, FRED!"と表示

関数について、詳しくはこちらのドキュメントをご覧ください。

クラス

Pythonでは、とても分かりやすい構文でクラスが定義できます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Greeter(object):
 
    # コンストラクタ
    def __init__(self, name):
        self.name = name # インスタンス変数を作成
 
    # インスタンスメソッド
    def greet(self, loud=False):
        if loud:
            print('HELLO, %s!' % self.name.upper())
        else:
            print('Hello, %s' % self.name)
 
g = Greeter('Fred') # Greeterクラスのインスタンスを生成
 
g.greet() # インスタンスメソッドを呼び出す; "Hello, Fred"と表示
 
g.greet(loud=True) # インスタンスメソッドを呼び出す; "HELLO, FRED!"と表示

クラスについて、詳しくはこちらのドキュメントをご覧ください。

トップに戻る

Numpy

NumpyはPythonにおけるデータ・情報処理の中核をなすライブラリです。

高性能な多次元数値配列や、配列を操作するツールが提供されています。

MATLABに精通している方であれば、こちらのチュートリアルもご参照ください。

配列

Numpyにおける配列は要素が格子状に並んだ形をとり、要素の値はすべて同じ型で、非負整数のタプルでインデックスが振られます。

配列の次元数は階数(rank)と呼ばれ、配列の形状(shape)は次元ごとの配列の大きさを整数のタプルで表します。

配列はネストされたリストから作成でき、ブラケット(角括弧)で配列内の要素を呼び出すことができます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import numpy as np
 
a = np.array([1, 2, 3]) # 階数1の配列を作成
 
print(type(a)) # "<class 'numpy.ndarray'>"と表示
 
print(a.shape) # "(3,)"と表示
 
print(a[0], a[1], a[2]) # "1 2 3"と表示
 
a[0] = 5 # 配列の要素を変更
 
print(a) # "[5 2 3]"と表示
 
b = np.array([[1,2,3],[4,5,6]]) # 階数2の配列を作成
 
print(b.shape) # (2, 3)"と表示
 
print(b[0, 0], b[0, 1], b[1, 0]) # "1 2 4"と表示

Numpyは配列を作成するための関数も多く備えています。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import numpy as np
 
a = np.zeros((2,2)) # すべて0の配列を作成
 
print(a) # "[[ 0. 0.]
# [ 0. 0.]]"と表示
 
b = np.ones((1,2)) # すべて1の配列を作成
 
print(b) # "[[ 1. 1.]]"と表示
 
c = np.full((2,2), 7) # 任意の定数配列を作成
 
print(c) # "[[ 7 7]
# [ 7 7]]"と表示
 
d = np.eye(2) # 2x2の単位行列を作成
 
print(d) # "[[ 1. 0.]
# [ 0. 1.]]"と表示
 
e = np.random.random((2,2)) # 無作為な値の配列を作成
 
print(e) # "[[ 0.91940167 0.08143941]
# [ 0.68744134 0.87236687]]"と表示(一例)

配列作成のメソッドについて、詳しくはこちらのドキュメントをご覧ください。

配列のインデックス参照

Numpyでは配列の要素を参照する方法が色々用意されています。

スライス: リストと同じように、Numpyの配列もスライスできます。

配列は多次元なので、配列の次元ごとにスライスを指定する必要があります。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import numpy as np
 
# 以下の、階数2、形状(3, 4)の配列を作成
# [[ 1 2 3 4]
# [ 5 6 7 8]
# [ 9 10 11 12]]
 
a = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]])
 
# スライスを用い、初めの2行と2,3列目を抽出
# bは以下の、形状(2, 2)の配列
# [[2 3]
# [6 7]]
 
b = a[:2, 1:3]
 
# 配列のスライスは元の配列と同じデータを参照するため、
# スライスで作成した配列を変更すると元の配列も同様に変更される
 
print(a[0, 1]) # "2"と表示
 
b[0, 0] = 77 # b[0, 0]はa[0, 1]と同じデータを参照
 
print(a[0, 1]) # "77"と表示

インデックスの参照では、整数とスライスを同時に使用することもできます。

しかしそうすると、配列の階数が元の配列より一つ低くなります。

これはMATLABの配列スライスとは大きく異なる点なので注意してください。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import numpy as np
 
# 以下の、階数2、形状(3, 4)の配列を作成
# [[ 1 2 3 4]
# [ 5 6 7 8]
# [ 9 10 11 12]]
 
a = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]])
 
# 配列の真ん中の行にあるデータを取り出す方法は二通り用意されている
# 整数とスライスを同時に使う場合は階数が下がる
# スライスのみの場合は階数が変わらない
 
row_r1 = a[1, :] # aの2行目が階数1として取り出される
row_r2 = a[1:2, :] # aの2行目が階数2のまま取り出される
 
print(row_r1, row_r1.shape) # "[5 6 7 8] (4,)"と表示
print(row_r2, row_r2.shape) # "[[5 6 7 8]] (1, 4)"と表示
 
# 配列の列を取り出すときも同様の区別がなされる。
 
col_r1 = a[:, 1]
col_r2 = a[:, 1:2]
 
print(col_r1, col_r1.shape) # "[ 2 6 10] (3,)"と表示
 
print(col_r2, col_r2.shape) # "[[ 2]
# [ 6]
# [10]] (3, 1)"と表示

ファンシーインデックス参照: スライスを使ってNumpy配列のインデックスを参照する場合、取り出した配列は常に元の配列の並びを保ったままです。

一方ファンシーインデックス参照を使えば、任意の行と列から要素を抽出できます。

以下がその例です。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import numpy as np
 
a = np.array([[1,2], [3, 4], [5, 6]])
 
# ファンシーインデックス参照の例
# 表示される配列は形状(3,)を持ち、
 
print(a[[0, 1, 2], [0, 1, 0]]) # "[1 4 5]"と表示
 
# 上記の例は以下と同様
print(np.array([a[0, 0], a[1, 1], a[2, 0]])) #"[1 4 5]"と表示
 
# ファンシーインデックス参照では同じ要素の抽出も可能
print(a[[0, 0], [1, 1]]) # "[2 2]"と表示
 
# 上記の例は以下と同様
print(np.array([a[0, 1], a[0, 1]])) # "[2 2]"と表示

ファンシーインデックス参照の便利な使い方として、配列の各行から要素を一つずつ抽出したり変更したりできます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import numpy as np
 
# 要素抽出用に新しい配列を作成
 
a = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]])
 
print(a) # "[[ 1, 2, 3]
# [ 4, 5, 6]
# [ 7, 8, 9]
# [10, 11, 12]]"と表示
 
# インデックスの配列を作成
 
b = np.array([0, 2, 0, 1])
 
# aからインデックス配列bを使って各行の要素を一つずつ取り出す
 
print(a[np.arange(4), b]) # Prints "[ 1 6 7 11]"
 
# aからインデックス配列bを使って各行の要素を一つずつ変更する
 
a[np.arange(4), b] += 10
 
print(a) # "[[11, 2, 3]
# [ 4, 5, 16]
# [17, 8, 9]
# [10, 21, 12]]"と表示

ブールインデックス参照: ブールインデックス参照では、配列の任意の要素を取り出せます。

このインデックス参照は、与えた条件に合致する要素を抽出する目的でよく使われます。

以下がその例です。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import numpy as np
 
a = np.array([[1,2], [3, 4], [5, 6]])
 
bool_idx = (a > 2) # aから2より大きい値を持つ要素を見つける
# bool_idxの判定結果に即したブール型の要素を持った、
# aと同じ大きさの配列を返す
 
print(bool_idx) # "[[False False]
# [ True True]
# [ True True]]"と表示
 
# ブールインデックス配列は以下のようにして、
# bool_idxの判定結果Trueの要素のみを取り出し、
# 階数1の配列として表示する
 
print(a[bool_idx]) # "[3 4 5 6]"と表示
 
# 上記のことは以下のように一行でも表せる
print(a[a > 2]) # "[3 4 5 6]"と表示

Numpy配列のインデックス参照について、詳しくはこちらのドキュメントをご覧ください。

データ型

Numpyでは、数値に関するデータ型が豊富に用意されています。

配列を作る際、Numpyは自動的に要素のデータ型を予測してくれますが、追加で引数として与えることでデータ型を指定する機能もついています。

以下がその例です。

1
2
3
4
5
6
7
8
9
10
11
12
13
import numpy as np
 
x = np.array([1, 2]) # 自動的にデータ型を選択
 
print(x.dtype) # "int64"と表示
 
x = np.array([1.0, 2.0]) # 自動的にデータ型を選択
 
print(x.dtype) # "float64"と表示
 
x = np.array([1, 2], dtype=np.int64) # 特定のデータ型を指定
 
print(x.dtype) # "int64"と表示

Numpyのデータ型について、詳しくはこちらをご覧ください。

配列の演算

基本的な数学関数は、配列の要素ごとに機能します。

また演算子のオーバーロードとしてもNumpyの関数としても利用できます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import numpy as np
 
x = np.array([[1,2],[3,4]], dtype=np.float64)
y = np.array([[5,6],[7,8]], dtype=np.float64)
 
# 要素ごとの和; 共に配列を生成
# [[ 6. 8.]
# [10. 12.]]
 
print(x + y)
 
print(np.add(x, y))
 
# 要素ごとの差; 共に配列を生成
# [[-4. -4.]
# [-4. -4.]]
 
print(x - y)
 
print(np.subtract(x, y))
 
# 要素ごとの積; 共に配列を生成
# [[ 5. 12.]
# [21. 32.]]
 
print(x * y)
 
print(np.multiply(x, y))
 
# 要素ごとの商; 共に配列を生成
# [[ 0.2 0.33333333]
# [ 0.42857143 0.5 ]]
 
print(x / y)
 
print(np.divide(x, y))
 
# 要素ごとの平方根; 配列を生成
# [[ 1. 1.41421356]
# [ 1.73205081 2. ]]
 
print(np.sqrt(x))

ドット積: MATLABとは異なり、*は要素ごとの積です。

行列の積ではないので注意してください。

代わりに、ベクトルの内積、ベクトルと行列の掛け算、行列同士の掛け算にはdotを使用します。

dotはnumpyの関数としても配列のメソッドとしても使用できます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import numpy as np
 
x = np.array([[1,2],[3,4]])
y = np.array([[5,6],[7,8]])
 
v = np.array([9,10])
w = np.array([11, 12])
 
# ベクトルの内積; 共に219
 
print(v.dot(w))
 
print(np.dot(v, w))
 
# 行列とベクトルの積; 共に階数1の配列[29 67]を生成
 
print(x.dot(v))
 
print(np.dot(x, v))
 
# 行列と行列の積; 共に階数2の配列
# [[19 22]
# [43 50]]を生成
 
print(x.dot(y))
 
print(np.dot(x, y))

和: Numpyは配列演算のための便利な関数を多数用意しています。

その一つがsumです。

1
2
3
4
5
6
7
8
9
import numpy as np
 
x = np.array([[1,2],[3,4]])
 
print(np.sum(x)) # すべての要素の和を計算; "10"と表示
 
print(np.sum(x, axis=0)) # 列ごとの和を計算; "[4 6]"と表示
 
print(np.sum(x, axis=1)) # 行ごとの和を計算; "[3 7]"と表示

Numpyで使える数学関数について、詳しくはこちらをご覧ください。

転置: 配列を用いた数学演算のほかに、配列内のデータを作り変えたり操作したりすることもあります。

このタイプの例として、行列の転置があります。

転置行列を作るには、配列の属性Tを使います。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import numpy as np
 
x = np.array([[1,2], [3,4]])
 
print(x) # "[[1 2]
# [3 4]]"と表示
 
print(x.T) # "[[1 3]
# [2 4]]"と表示
 
# 階数1の配列で転置行列を作ろうとしても何も起こらない
v = np.array([1,2,3])
 
print(v) # "[1 2 3]"と表示
 
print(v.T) # "[1 2 3]"と表示

Numpyには配列を操作するための関数がとても多く存在します。

詳しくはこちらをご覧ください。

ブロードキャスト

ブロードキャストは、階数や形状が異なる配列同士でも処理ができるようにする強力な仕組みです。

階数や形状が大きい配列と小さい配列があるとき、小さい方の配列を複数回用いて、大きい方の配列に演算処理を施すものです。

例として、行列の各行に定ベクトルを加えようと思います。以下のようになります。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import numpy as np
 
# 行列xの各行にベクトルvを加え、結果を行列yに入れる
 
x = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]])
v = np.array([1, 0, 1])
y = np.empty_like(x) # xと形状が等しい空の行列を作成
 
# ベクトルvを、ループを使って行列xの各行に加える
for i in range(4):
    y[i, :] = x[i, :] + v
 
    # yは以下の通り
    # [[ 2 2 4]
    # [ 5 5 7]
    # [ 8 8 10]
    # [11 11 13]]
 
print(y)

これはこれで機能します。

しかし行列xがとても大きい場合、Pythonでこのループを回すととても遅くなってしまいます。

ここで、ベクトルvを行列xの各行に加えるということは、ベクトルvを垂直方向に複数回重ねた行列vvを作り、要素ごとに行列xとvvを足し算することと同じです。

以上のことは、以下のように行えます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import numpy as np
 
# 行列xの各行にベクトルvを加え、結果を行列yに入れる
 
x = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]])
v = np.array([1, 0, 1])
vv = np.tile(v, (4, 1)) # vを複製し4回重ねる
 
print(vv) # "[[1 0 1]
# [1 0 1]
# [1 0 1]
# [1 0 1]]"と表示
 
y = x + vv # xとvvを要素ごとに加える
 
print(y) # "[[ 2 2 4
# [ 5 5 7]
# [ 8 8 10]
# [11 11 13]]"と表示

Numpyのブロードキャストでは、実際にvを複製して重ねるということをしないでも計算を行ってくれます。

上の計算をブロードキャストを使って行うと、以下のようになります。

1
2
3
4
5
6
7
8
9
10
11
12
import numpy as np
 
# 行列xの各行にベクトルvを加え、結果を行列yに入れる
 
x = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]])
v = np.array([1, 0, 1])
y = x + v # ブロードキャストを使用してvをxの各行に加える
 
print(y) # "[[ 2 2 4]
# [ 5 5 7]
# [ 8 8 10]
# [11 11 13]]"と表示

xは形状(4, 3)、vは形状(3,)ですが、y = x + vはしっかり機能します。

これはブロードキャストによって、vが自身を複製した形状(4, 3)として機能し、要素ごとに合計が計算されたためです。

二つの配列をブロードキャストする際は、以下のルールに従います。

1. 配列の階数が同じでない場合、両配列の形状が同じになるまで、階数の低い配列の形状に1を付け加える。(例:(3, ) → (1, 3) → (1, 1, 3) )
2. ある次元において、二つの配列の要素数が等しいか、どちらかが1であるとき、二つの配列は互換性がある(compatible)と言う。
3. 全次元において互換性があれば、その配列はブロードキャストすることができる。
4. ブロードキャストすると、配列の形状は、二つの配列の形状のうち、次元ごとに大きい方を持つものとして扱われる。(例:(3, 1, 1) と (1, 4, 2) → (3, 4, 2) )
5. ある次元において、一方の配列の大きさが1、もう一方は1より大きい場合、最初の配列はその次元にそって複製されたようにふるまう。

この説明が不十分だった場合は、こちらのドキュメントもしくはこちらの説明をご参照ください。

ブロードキャストに対応した関数はユニバーサル関数として知られています。

詳しくはこちらのドキュメントをご覧ください。

以下はブロードキャストの使用例です。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import numpy as np
 
# ベクトルの外積を計算
 
v = np.array([1,2,3]) # vの形状は(3,)
w = np.array([4,5]) # wの形状は(2,)
 
# 外積を計算するには、まずvを形状(3, 1)の列ベクトルにし、
# wに対してブロードキャストして形状(3, 2)とする
# vとwの外積は以下の通り
# [[ 4 5]
# [ 8 10]
# [12 15]]
 
print(np.reshape(v, (3, 1)) * w)
 
# 行列の各行にベクトルを加える
 
x = np.array([[1,2,3], [4,5,6]])
 
# xは形状(2, 3)を、vは形状(3,)を持つので、
# ブロードキャストして(2, 3)となる
# 求める行列は以下の通り
# [[2 4 6]
# [5 7 9]]
 
print(x + v)
 
# 行列の各列にベクトルを加える
# xは形状(2, 3)を持ち、wは形状(2,)を持つ
# xを転置すると形状(3, 2)となり、wに対してブロードキャストすると形状(3, 2)となる
# この結果を転置すると形状(2,3)となり、これが行列xの各列にベクトルwを加えたものとなる
# 結果は以下の通り
# [[ 5 6 7]
# [ 9 10 11]]
 
print((x.T + w).T)
 
# もしくは、wを形状(2, 1)の列ベクトルに変換すれば、
# xに対して直接ブロードキャストすることができる
 
print(x + np.reshape(w, (2, 1)))
 
# 行列を定数倍する
# xは形状(2, 3)で、Numpyはスカラを形状()として扱う
# これらはブロードキャストして形状(2, 3)となり、以下の行列を生成
# [[ 2 4 6]
# [ 8 10 12]]
 
print(x * 2)

ブロードキャストはコードをより簡潔に、実行速度を早くしてくれるので、できるだけ使うようにしましょう。

Numpyドキュメント

以上でNumpyの重要な点には触れましたが、まだまだ色々なものが用意されています。

詳しくはこちらのドキュメントをご覧ください。

トップに戻る

SciPy

Numpyは高機能な多次元数値配列や、配列に操作するツールを提供しています。

SciPyはNumpyをベースとし、Numpyの配列で扱う大量の関数を備えており、様々な科学技術計算に適しています。

SciPyを知る一番の方法は公式ドキュメントを読むことです。有益そうな部分をいくつかご紹介します。

点と点の距離

SciPyには点集合間の距離を計算する便利な関数が備わっています。

関数scipy.spatial.distance.pdistは、与えられた集合のすべての点同士の距離を計算します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import numpy as np
from scipy.spatial.distance import pdist, squareform
# 2次元空間に各行が点の配列を作成
# [[0 1]
# [1 0]
# [2 0]]
x = np.array([[0, 1], [1, 0], [2, 0]])
print(x)
# xのすべての行の間のユークリッド距離を計算
# d[i, j]はx[i, :]とx[j, :]間のユークリッド距離で、
# dは以下の配列となる
# [[ 0. 1.41421356 2.23606798]
# [ 1.41421356 0. 1. ]
# [ 2.23606798 1. 0. ]]
d = squareform(pdist(x, 'euclidean'))
print(d)

 

詳しくはこちらのドキュメントをご覧ください。

似たような関数にscipy.spatial.distance.cdistというものがあり、こちらは二つの点集合のすべてのペアにわたって距離を計算します。

PIL

PIL(Python Imaging Library)は画像を操作する基本的な関数を備えているlibraryの一つです。

PIL公式ドキュメント

オープンソース ライブラリであり、画像をディスクから読み取りNumpyの配列に入れる、Numpyの配列から画像をディスクに書き込む、画像をリサイズするなどが可能です。

以下が簡単な例です。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 画像の操作
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
 
# JPEG画像を読み込みNumpyの配列に入れる
img = np.array(Image.open('cat.jpg'))
 
print(img.dtype, img.shape)# "uint8 (400, 248, 3)"と表示
 
# 異なったスカラー数でカラーチャネルを調整することで
# 画像の色合いを変えられる。画像は形状(400, 248, 3)を持つ
# 形状(3,)の配列[1, 0.95, 0.9]をこれに掛ける
# ブロードキャストすることで、赤のチャネルは変化なく残り、
# 緑と青のチャネルはそれぞれ0.95と0.9が掛けられる
 
color = img*[1,0.95,0.9]
 
#配列から画像に変換する際、float型ではエラーが出るためuint8に変換する
color = color.astype("uint8")
 
# #NumPyの配列を画像に変換する
im = Image.fromarray(color)
 
# # # 色合いを変えた画像を300×300ピクセルにリサイズする
im = im.resize((300,300))
 
# 色合いを変えた画像をディスクに書き込む
im.save('cat_tinted.jpg')#任意の保存先ファイル名

 

元の画像

色合いを変えてリサイズした画像

Matplotlib

Matplotlibはグラフ描画ライブラリです。

このセクションではMATLABに似たプロットシステムを提供するmatplotlib.pyplotを簡単に紹介します。

プロット

matplotlibで特に重要な関数は、二次元データをプロットしてくれるplotです。

以下がその例です。

1
2
3
4
5
6
7
8
9
10
11
12
import numpy as np
import matplotlib.pyplot as plt
# 正弦波の点に対応するxとyを計算
x = np.arange(0, 3 * np.pi, 0.1)
y = np.sin(x)
# matplotlibを用いてプロットを表示
plt.plot(x, y)
plt.show() # 画像を表示するにはshow()を呼び出す必要あり

このコードを実行することで、以下のプロットが表示されます。

もう少し手を加えるだけで、簡単に複数のグラフを表示させたり、タイトルや凡例、軸のラベルを加えることができます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import numpy as np
import matplotlib.pyplot as plt
# 正弦波・余弦波の点に対応するxとyを計算
x = np.arange(0, 3 * np.pi, 0.1)
y_sin = np.sin(x)
y_cos = np.cos(x)
# matplotlibを用いプロットを表示
plt.plot(x, y_sin)
plt.plot(x, y_cos)
plt.xlabel('x axis label')
plt.ylabel('y axis label')
plt.title('Sine and Cosine')
plt.legend(['Sine', 'Cosine'])
plt.show()

詳しくはこちらをご覧ください。

サブプロット

subplot関数を使えば、異なった物事を同じ図の中にプロットすることができます。

以下がその例です。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import numpy as np
import matplotlib.pyplot as plt
# 正弦波・余弦波の点に対応するxとyを計算
x = np.arange(0, 3 * np.pi, 0.1)
y_sin = np.sin(x)
y_cos = np.cos(x)
# 高さ2、幅1のサブプロットを設定し、最初のサブプロットを指定
plt.subplot(2, 1, 1)
# 最初のプロットを作成
plt.plot(x, y_sin)
plt.title('Sine')
# 二番目のサブプロットを指定し、二番目のプロットを作成
plt.subplot(2, 1, 2)
plt.plot(x, y_cos)
plt.title('Cosine')
# 図を表示
plt.show()

画像の表示

imshow関数で画像を表示できます。

以下が例です。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import numpy as np
from matplotlib.pyplot import imread, imsave, imshow
import matplotlib.pyplot as plt
img = imread('cat.jpg')
img_tinted = img * [1, 0.95, 0.9]
# 元の画像を表示
plt.subplot(1, 2, 1)
plt.imshow(img)
# 色合いを変えた画像を表示
plt.subplot(1, 2, 2)
# uint8以外のデータ型でimshowを使うと、変な結果になることがある
# これを防ぐため、表示する前に画像を明示的にuint8にする
plt.imshow(np.uint8(img_tinted))
plt.show()

トップに戻る

あなたも、Avintonでこのような最先端技術を習得し活用してみませんか?

社員の成長を導きながら、AIやビッグデータなどの最先端技術をプロジェクトに活用していくことが私たちのビジョンです。Avintonの充実した技術研修でスキルアップを図り、あなたのキャリア目標を一緒に達成しませんか?

採用情報

採用情報

採用情報

Categories

  • 相互学習
  • 採用
  • 社員インタビュー
  • 学習&資格取得
  • 技術解説
  • イベント告知
  • 学内説明会&講義
  • 産学連携
  • 就職活動
  • イベントレポート
  • その他
  • 技術ブログ&インタビュー
  • mainpage
  • New Graduates Interviews
  • 中途エンジニア
  • カテゴリーなし
  • ニュースリリース&イベント

Avinton SDGs

SDGsへの貢献

Search

タグ

AIエンジニア AI導入 Apatch AvintonAcademy CKA DevOps KiX Kubernetes Notion PM&PMO PyTorch SDGs Innnovation Hub UI YOLOv5 アカウントマネージャー インタビュー インフラエンジニア エッジAIカメラ セキュリティエンジニア ソフトスキル ツール開発 データサイエンティスト ネットワークエンジニア フルスタックエンジニア フロントエンド ベテランエンジニア ボランティア マイクロサービス モーフィング ローカルイベント 中瀬幸子、サーバークラスター 中途採用 人材育成 協働パートナー 国際自動制御連盟 地域創生 基本情報技術者 強化学習 技術 新卒、キャリア 新卒採用 田中研之輔 社会貢献 経団連 顔認証
© 2023 Avinton | All Rights Reserved | プライバシーポリシー
  • サービス
    • Avinton Data Platform
    • エッジAIカメラ
      • 自動車ナンバープレート自動認識システム
    • プライベートクラウド
    • AIサービス開発
    • AIカメラ/画像解析無料体験版
  • 最新情報
    • ニュースリリース&イベント情報
    • 技術ブログ&インタビュー
  • アカデミー
    • Avintonアカデミー
    • Academy on Campus
    • Academy with Platform
  • 採用情報
    • Avintonジャパン 採用ページ
    • 求人一覧
    • よくある質問
    • 新卒採用
  • 企業情報
    • 会社概要
    • 代表からご挨拶
    • SDGsへの貢献
  • お問い合わせ
  • 日本語
    • English (英語)
Avinton Japan