質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
多次元配列

1次元配列内にさらに配列を格納している配列を、多次元配列と呼びます。

NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

Socket.IO

Socket.IOはNode.js上で動くライブラリであり、すべてのブラウザとモバイルデバイスでリアルタイムのアプリを作動させる事を目的としています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

2回答

3085閲覧

socket通信で2Dのnumpy配列を汎用的に(サイズやデータ型もふくめて)通信したい

xsteviax

総合スコア14

多次元配列

1次元配列内にさらに配列を格納している配列を、多次元配列と呼びます。

NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

Socket.IO

Socket.IOはNode.js上で動くライブラリであり、すべてのブラウザとモバイルデバイスでリアルタイムのアプリを作動させる事を目的としています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2020/04/06 03:19

編集2020/04/06 05:47

実現したいこと・質問

  • socket通信で2Dのnumpy配列を汎用的に(サイズやデータ型もふくめて)通信したい。

  • 以下に示すようにクライアント側とサーバ側それぞれにサイズやデータ型を予め設定したり、サイズやデータ型を改めてクライアント側からサーバー側へ通信することで実装できますが、このような暫定的な方法ではなく、2Dのnumpy配列を転送する推奨された方法はありますか?

以下、前提

  • 現在、2Dのnumpy通信を受信側、送信側に予めサイズやデータ型を設定することで通信できている。

クライアント側

python

1import socket 2import numpy as np 3 4PORT = 11113 5BUFFER_SIZE = 1024 6 7with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: 8 s.connect(('server_container', PORT)) 9 data = np.arange(30) 10 data = np.reshape(data,(5,6)) 11 print(data) 12 data = data.tostring() 13 s.send(data) 14 data2 = s.recv(BUFFER_SIZE) 15 data2 = np.fromstring(data2,dtype=np.int64) 16 data2 = np.reshape(data2,(5,6)) 17 print(data2)

サーバー側

python

1import socket 2import numpy as np 3 4PORT = 11113 5BUFFER_SIZE = 1024 6 7with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: 8 s.bind(('0.0.0.0', PORT)) 9 s.listen() 10 while True: 11 (connection, client) = s.accept() 12 try: 13 print('Client connected', client) 14 data = connection.recv(BUFFER_SIZE) 15 data = np.fromstring(data,dtype=np.int64) 16 data = np.reshape(data,(5,6)) 17 print(data) 18 data = data.tostring() 19 connection.send(data) 20 finally: 21 connection.close()

試したこと(追記)

np.saveとnp.loadを用いコードを書き直しし、互いに通信しようとしたところ、
サーバ側のnp.loadでデシリアライズできませんでした。

  • サーバー側19行目「print(data2)」のブレークポイントでデバッグ

debug

1data2 2array(<function save at 0x7fd590150f28>, dtype=object)

以下、修正コード

  • クライアント側

python

1from io import BytesIO 2 3import socket 4import numpy as np 5 6PORT = 11113 7BUFFER_SIZE = 2048 8out = BytesIO() 9 10with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: 11 s.connect(('server_container', PORT)) 12 data = np.arange(30) 13 data = np.reshape(data,(5,6)) 14 print(data) 15 np.save(out, np.save) 16 binary = out.getvalue() 17 s.send(binary) 18 data2 = s.recv(BUFFER_SIZE) 19 data2 = np.load(BytesIO(data2), allow_pickle=True) 20 print(data2)
  • サーバー側

python

1from io import BytesIO 2 3import socket 4import numpy as np 5 6PORT = 11113 7BUFFER_SIZE = 2048 8out = BytesIO() 9 10with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: 11 s.bind(('0.0.0.0', PORT)) 12 s.listen() 13 while True: 14 (connection, client) = s.accept() 15 try: 16 print('Client connected', client) 17 data = connection.recv(BUFFER_SIZE) 18 data2 = np.load(BytesIO(data), allow_pickle=True) 19 print(data2) 20 np.save(out, data2) 21 binary = out.getvalue() 22 connection.send(binary) 23 finally: 24 connection.close()

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

numpy.save で npy 形式でバイナリ化してはどうでしょうか。この形式の場合、バイナリ内に型やサイズの情報が含まれているため、numpy.load で読み込めば、そのまま元の配列を復元できます。

python

1from io import BytesIO 2 3import numpy as np 4 5a = np.arange(10) 6 7# numpy -> npy format 8out = BytesIO() 9np.save(out, a) 10binary = out.getvalue() 11 12# npy format -> numpy 13a = np.load(BytesIO(binary)) 14print(a)

投稿2020/04/06 03:52

tiitoi

総合スコア21956

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

xsteviax

2020/04/06 04:35

回答ありがとうございます。 np.saveとnp.loadを少し試してみようと思います。
xsteviax

2020/04/06 05:44

np.saveとnp.loadを用いコードを書き直しし、互いに通信しようとしたところ、 サーバ側のnp.loadでデシリアライズできませんでした。 内容は本文に追記いたしました。
tiitoi

2020/04/06 05:51

`np.save(out, np.save)` はおかしくないでしょうか。 save の第2引数は送りたい配列を指定します。
xsteviax

2020/04/06 05:57

おっしゃるとおりでした。 恥ずかしいミスをしてしまいました。。。 こちらの方法で通信問題なくできましたので、ベストアンサーに選択したいと思います。 質問に答えてくださった方々ありがとうございました。
guest

0

そういう、「任意のオブジェクトをバイト列に変換して、あとでオブジェクトに復元する」というのは、シリアライズ、デシリアライズ、と言います。

いくつかライブラリがあります。標準の物なら、
pickle
marshal
など。

他は、「Python シリアライズ」「Python 直列化」などでググってください。

投稿2020/04/06 03:25

otn

総合スコア84555

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

otn

2020/04/06 03:51 編集

numpyオブジェクトだと、np.save等でシリアライズできるようですが、ファイルに書くしかできなさそうです。 いったんファイルを経由することになりますが、これだと間違いないかと。
xsteviax

2020/04/06 04:34

回答ありがとうございます。 「シリアライズ」初めて聞きました。調べてみます。 あと、np.saveを少し試してみようと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問