ブログ

割とコンピュータよりの情報をお届けします。

Python

Python numpyでFFTを実行する.周波数軸はどうしたら4

前の記事ではnumpy.fft.fftfreqをプロットの時の範囲指定に使うことしか考えていなかったが,フィルタなどもできる.

numpy.fft.fftfreqによって生成した周波数軸とnumpy.whereを使うと周波数でフィルタリングが行える.
例えば,
Fzf = np.fft.fft(z);
Fz2f = np.where(np.abs(freq2) > 12, 0, Fzf)
などとすれば,周波数成分を取り除くことができる(0で埋めることができる).
np.fft.ifftで時間領域の信号に戻せば0で埋めた成分は消えている.

import numpy as np
import matplotlib.pyplot as plt

# 例の信号を作成
t = np.linspace(0.001, 4, 1000);
z = 0.1 + 0.2 * np.sin(t * 10 * 2 * np.pi) + 0.2 * np.sin(t * 33 * 2 * np.pi);

# サンプリング周波数
fsmp = 1 / (t[1] - t[0]);
# 解析時間
t_len = t.max() - t.min();

Fzf = np.fft.fft(z); # Fzfはfftした結果
Fz = Fzf / z.shape[0] * 2; # 折り返すのでパワーが2分の1になっている.
Fz[0] = Fz[0] / 2; # 平均成分は折り返さない.
Fz_abs = np.abs(Fz);


freq2 = np.fft.fftfreq(len(t), d=1.0/fsmp);# 周波数軸の生成

# abs(freq2)が12以上の成分をカット
Fz2f = np.where(np.abs(freq2) > 12, 0, Fzf) # filter
z_filtered = np.fft.ifft(Fz2f);
Fz2 = Fz2f / z.shape[0] * 2;
Fz2[0] = Fz2[0] / 2;
Fz2_abs = np.abs(Fz2);


plt.figure(1)
# 比較FFTプロット
plt.subplot(211);
plotrange = np.where(freq2 >= 0)
plt.plot(freq2[plotrange], Fz_abs[plotrange]);
plt.plot(freq2[plotrange], Fz2_abs[plotrange]);

# 比較波形プロット
plt.subplot(212);
plt.plot(t, z);
plt.plot(t, z_filtered);

plt.savefig("valuestar.work.177.png")

plt.show();


≫ Read More

2021/04/03 コンピュータ   TakeMe
Tag:Python

Python numpyでFFTを実行する.周波数軸はどうしたら3

以前の記事「Python numpyでFFTを実行する.周波数軸はどうしたら」「Python numpyでFFTを実行する.周波数軸はどうしたら」ではlinspaceを使って周波数リストを出力していたのをnumpy.fft.fftfreqでもよいと書いていたが,,,

numpy.fft.fftfreqで作る次のようなコードではfreq2は途中でいきなり負に飛ぶことになり,plt.plot(freq2, Fz_abs);とするとプロットが汚くなる.xlimで範囲制限をしても枠外の点とつながった線が気になる.

import numpy as np
import matplotlib.pyplot as plt

# 例の信号を作成
t = np.linspace(0.001, 4, 1000);
z = 0.1 + 0.2 * np.sin(t * 10 * 2 * np.pi) + 0.2 * np.sin(t * 33 * 2 * np.pi);

# サンプリング周波数
fsmp = 1 / (t[1] - t[0]);
# 解析時間
t_len = t.max() - t.min();

Fz = np.fft.fft(z) / z.shape[0] * 2; # 折り返すのでパワーが2分の1になっている.
Fz[0] = Fz[0] / 2; # 平均成分は折り返さない.
Fz_abs = np.abs(Fz);

freq = np.linspace(0, fsmp - 1.0/(t_len + t[1] - t[0]), num=len(t));
freq2 = np.fft.fftfreq(len(t), d=1.0/fsmp);

plt.figure(1)
plt.plot(freq, Fz_abs);

plt.figure(2)
plt.plot(freq2, Fz_abs);
plt.xlim([0, 125])


plt.show();

たとえば,np.where(freq2 >= 0, freq2, np.nan)で選別してもよい.要素がNaNになっているとプロットに失敗するので描画されない(plt.figure(3)に示した).
もしくは,np.where(freq2 >=0)でインデックス列の状態にしておいてそれでプロット範囲を周波数で制限することも可能でplt.figure(4)に示した.

import numpy as np
import matplotlib.pyplot as plt

# 例の信号を作成
t = np.linspace(0.001, 4, 1000);
z = 0.1 + 0.2 * np.sin(t * 10 * 2 * np.pi) + 0.2 * np.sin(t * 33 * 2 * np.pi);

# サンプリング周波数
fsmp = 1 / (t[1] - t[0]);
# 解析時間
t_len = t.max() - t.min();

Fz = np.fft.fft(z) / z.shape[0] * 2; # 折り返すのでパワーが2分の1になっている.
Fz[0] = Fz[0] / 2; # 平均成分は折り返さない.
Fz_abs = np.abs(Fz);

freq = np.linspace(0, fsmp - 1.0/(t_len + t[1] - t[0]), num=len(t));
freq2 = np.fft.fftfreq(len(t), d=1.0/fsmp);

plt.figure(1)
plt.plot(freq, Fz_abs);

plt.figure(2)
plt.plot(freq2, Fz_abs);
plt.xlim([0, 125])

freq3 = np.where(freq2 >= 0, freq2, np.nan)
plt.figure(3)
plt.plot(freq3, Fz_abs);

plt.figure(4)
plotrange = np.where(freq2 >= 0)
plt.plot(freq2[plotrange], Fz_abs[plotrange]);

plt.show();

≫ Read More

2021/03/30 コンピュータ   TakeMe
Tag:Python

Python for .NETの新しい話 Vol. 2

Pythonでsgolayフィルタを使ってみた..NETでもオープンソースのコードがないかなと思っていたのですが,なかなか見つからなかったのでscipyのコードを使うことにしてみた.

自分で探していたけど「SciPy で Savitzky-Golay フィルタ」という参考にmodeなるものも指定できることが分かった.SciPyの方が簡単かな

 

やっぱり簡単.ただし,Scipyはかなりストレージを使う.これを小さくできたらよいのだが...

C#側のコードは次のような感じにしてみた.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Python.Runtime;

namespace SgolaySample
{
    public partial class Form1 : Form
    {

        public Form1()
        {
            InitializeComponent();

            System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea1 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
            System.Windows.Forms.DataVisualization.Charting.Legend legend1 = new System.Windows.Forms.DataVisualization.Charting.Legend();
            System.Windows.Forms.DataVisualization.Charting.Series series1 = new System.Windows.Forms.DataVisualization.Charting.Series();
            System.Windows.Forms.DataVisualization.Charting.Series series2 = new System.Windows.Forms.DataVisualization.Charting.Series();
            this.chart1 = new System.Windows.Forms.DataVisualization.Charting.Chart();
            // 
            // chart1
            // 
            chartArea1.Name = "ChartArea1";
            this.chart1.ChartAreas.Add(chartArea1);
            legend1.Name = "Legend1";
            this.chart1.Legends.Add(legend1);
            this.chart1.Location = new System.Drawing.Point(12, 12);
            this.chart1.Name = "chart1";
            series1.ChartArea = "ChartArea1";
            series1.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Point;
            series1.Legend = "Legend1";
            series1.Name = "Series1";
            series2.ChartArea = "ChartArea1";
            series2.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
            series2.Legend = "Legend1";
            series2.Name = "Series2";
            this.chart1.Series.Add(series1);
            this.chart1.Series.Add(series2);
            this.chart1.Size = new System.Drawing.Size(446, 206);
            this.chart1.TabIndex = 0;
            this.chart1.Text = "chart1";


            this.Controls.Add(this.chart1);

            string strPath = Environment.GetEnvironmentVariable("PATH");

            string appDir = Directory.GetParent(Assembly.GetExecutingAssembly().Location).FullName + @"\python";

            Environment.SetEnvironmentVariable("PATH", Path.PathSeparator + appDir, EnvironmentVariableTarget.Process);


            List<double> x = new List<double>(); // Python listへの変換予定
            List<double> y = new List<double>(); // Python listへの変換予定

            Random random = new Random(0);
            for (int i = 0; i < 400; i++)
            {
                x.Add(0.01 * i);
                y.Add(Math.Sin(2.0 * Math.PI * x[i] / 1.0) + random.NextDouble());
            }

            using (Py.GIL())
            {
                dynamic sys = Py.Import("sys");
                // sample.pyを置くフォルダをパスに追加
                sys.path.append(Directory.GetParent(Assembly.GetExecutingAssembly().Location).FullName);
            }

            using (Py.GIL()) 
            {
                dynamic sample = Py.Import("sample");
                dynamic ya = sample.filterA(y); // numpy.arrayで返ってくる予定

                for (int i = 0; i < x.Count; i++) {
                    chart1.Series[0].Points.AddXY(x[i], y[i]);
                    chart1.Series[1].Points.AddXY(x[i], ((double[])ya)[i]);
                }
            }
        }
    }
}

sample.pyの例

import numpy as np
from scipy import signal

def filterA(y):
    ya = signal.savgol_filter(y, 101, 5);
    return ya;

≫ Read More

2021/02/22 コンピュータ   TakeMe

Python for .NETの新しい話

だいぶん前に「PythonからC#で書いた.NET Framewokのクラスライブラリを読みだす」1つ目2つ目
では.NET Frameworkのプログラムを読み出すことだった。

逆の「C#からPythonの関数を呼び出し」は更新が追い付いていないといって最新版をとってきていた。
多少最新バージョンからバージョンがずれていてもよいならpythonnet_py37_winなどなどnugetで入れられるようになっていた。むしろこちらの方が簡単だな。

nugetパッケージは.NET Frameworkならpythonnet_py37_winだし.NET Coreならpythonnet_netstandard_py37_win
やっぱりnugetパッケージは簡単.ただし,embeddable pythonをビルドターゲットフォルダに持ってきている。この参考でscipyまたはnumpyをインストールした方が便利。

ターゲットに入れて一緒に持ち運び....(scipyまで入れると相当 大きい)

using Python.Runtime;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace PythonEmbedSample
{
    class Program
    {
        static void Main(string[] args)
        {
            string strPath = Environment.GetEnvironmentVariable("PATH");

            string appDir = Directory.GetParent(Assembly.GetExecutingAssembly().Location).FullName + @"\python";

            Environment.SetEnvironmentVariable("PATH", Path.PathSeparator + appDir, EnvironmentVariableTarget.Process);

            using (Py.GIL())
            {
                PythonEngine.RunSimpleString("print('SAMPLE')");
            }
        }
    }
}

python37._pthの#import siteのコメントアウトを解除して,https://bootstrap.pypa.io/get-pip.pyをもらってきて,...
embeddable pythonのディレクトリでpython get-pip.pyを実行して,
python -m pip install scipyを実行して... scipyを使えるようになった

例えば,sample.pyを作る splineで補間する例を追加してみた.

import numpy as np
from scipy import interpolate

def spline(x, y, xi):
    x = np.array(x);
    y = np.array(y);
    xi = np.array(xi);
    f = interpolate.interp1d(x, y, kind="cubic", fill_value="extrapolate")
    yi = f(xi);
    return yi;

そしてC#の側を次のようにいじってsample.pyのモジュールを読み込むようにする.

using Python.Runtime;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace PythonEmbedSample
{
    class Program
    {
        static void Main(string[] args)
        {
            string strPath = Environment.GetEnvironmentVariable("PATH");

            string appDir = Directory.GetParent(Assembly.GetExecutingAssembly().Location).FullName + @"\python";

            Environment.SetEnvironmentVariable("PATH", Path.PathSeparator + appDir, EnvironmentVariableTarget.Process);

            using (Py.GIL())
            {
                dynamic sys = Py.Import("sys");
                // sample.pyを置くフォルダをパスに追加
                sys.path.append(Directory.GetParent(Assembly.GetExecutingAssembly().Location).FullName);


                dynamic sample = Py.Import("sample");
                
                List<double> x = new List<double>(); // Python listへの変換予定
                List<double> y = new List<double>(); // Python listへの変換予定

                for (int i = 0; i < 10; i++)
                {
                    x.Add(0.1 * i);
                    y.Add(Math.Sin(2.0 * Math.PI * x[i] / 1.0));
                }

                List<double> xi = new List<double>(); // Python listへの変換予定
                for (int i = 0; i < 100; i++)
                {
                    xi.Add(0.01 * i);
                }
                dynamic yi_ = sample.spline(x, y, xi); // numpy.arrayで返ってくる予定
                List<double> yi = new List<double>(); // List<double>への変換は暗黙的にできないため
                yi.AddRange((double[])yi_);

                {
                    StreamWriter sw = new StreamWriter("sample_init.csv");
                    for (int i = 0; i < x.Count; i++)
                    {
                        sw.WriteLine(string.Format("{0},{1}", x[i], y[i]));
                    }
                    sw.Close();
                }

                {
                    StreamWriter sw = new StreamWriter("sample_interp.csv");
                    for (int i = 0; i < xi.Count; i++)
                    {
                        sw.WriteLine(string.Format("{0},{1}", xi[i], yi[i]));
                    }
                    sw.Close();
                }
            }
        }
    }
}

≫ Read More

2021/02/17 コンピュータ   TakeMe
Tag:Python

WinPython 3.7.4はVSCode付もある

最近はWinPythonの配布ファイルの名前の付け方がわからなくてZeroを選ぶようにしていた.

ところが,最近の配布ファイルを見ているといつのころからなのか不明だが,Visual Studio Codeのポータブル版が同梱されたファイルがある.

このVisual Studio CodeはWinPythonと同様USBメモリなどリムーバブルメディアから起動できるようになっている.
Pythonのデバッグ設定関係もセットされていた.(最初の利用時には構成の追加で選択が必要)
Visual Studio Code日本語が必要なら,「Japanese Language Pack for Visual Studio Code」を追加すればよい.

PythonのデバッグにIDLEを使用していたが,ブレイクポイントの設定などでVSCodeの方がよく使用するIDEに似ていて便利かもしれない.

ただし,WinPythonの配布ファイルサイズは結構大きくなってきている.ファイルを展開して準備するまでの時間は相当要する.

≫ Read More

2019/09/29 コンピュータ   TakeMe
Tag:Python

Scipyのinterpolateはデータの外側へも広げられる

Scipyのinterpolateはデータの外側へも広げられることを知った.
fminなどを使用していると,引数が意図しない範囲に行って補間が失敗して止まることがあるのだが,未然に防ぐことができる.

scipyのinterpolateは今まで使ったことがなかったが,事前にx, yの2つの数値列を与えておくと補間するための関数を返してくれるという仕様になっている.この関数として返すという仕様がfminなどで使うときの便利さにつながる.
さらに,interpolateはデータの範囲が超えたときにエラーにしない仕様がある.例えば以下のような例である

# -*- coding: utf-8 -*-
import numpy as np
import scipy as scipy
from scipy.optimize import fmin
from scipy import interpolate
import matplotlib
import matplotlib.pyplot as plt

x = np.linspace(0, 100, num=1001, endpoint=True);
y = np.zeros(x.shape);

for i in range(y.shape[0]):
    if i < 500 and i > 50:
        y[i] = 1;
f4 = scipy.interpolate.interp1d(x, y, 'cubic', fill_value='extrapolate')
xi = np.linspace(-100, 200, num=121)

plt.plot(x, y, linewidth='3');
plt.plot(xi, f4(xi))
plt.grid(True)

plt.savefig('20190727test.png', format='png', dpi=100)
plt.show();

さらに数値最小化の追加の例までついかすると例えば以下のようになる.

# -*- coding: utf-8 -*-
import numpy as np
import scipy as scipy
from scipy.optimize import fmin
from scipy import interpolate
import matplotlib
import matplotlib.pyplot as plt

x = np.linspace(0, 100, num=1001, endpoint=True);
y = (x - 40) ** 2

f2 = scipy.interpolate.interp1d(x, y, 'cubic', fill_value='extrapolate')

minimum = scipy.optimize.fmin(f2, 1)

xi = np.linspace(-100, 200, num=121)

plt.plot(x, y, linewidth='3');
plt.plot(xi, f2(xi))
plt.plot(minimum, f2(minimum), '+')
plt.grid(True)

plt.savefig('20190727test2.png', format='png', dpi=100)
plt.show();

導関数を使わない数値最小化ならこれらでもよいが,微分係数を使って勾配を下に下らせるように最適化を目指すアルゴリズムを使用したい場合には,計算が増えてしまう.そこで,UnivariateSplineというものもある.まず上の置き換えだけなら,

from scipy.interpolate import UnivariateSplie
f2 = scipy.interpolate.UnivariateSpline(x, y, s=0, ext=0)

にするだけである.さらにf2.derivatives()なるものが使えるようになる
f2.derivatives(minimum)は[ほぼ0, ほぼ0, 2, ほぼ0]になるはず.順にf2の補間結果,1次微分係数,2次微分係数,...

≫ Read More

2019/07/27 コンピュータ   TakeMe
Tag:Python

Pythonのsounddeviceその2

Pythonでnumpyの信号をスピーカーから出力するのはどうすればよいのかを探していると,sounddeviceというのが見つかった.
これを使って前は少し遊んでみるた
sounddeviceにはplayrecという関数があって再生と録音を同時にできる.

音を入力出力する例としては,sd.playrec(z, samplerate=fs, channels=1)に変えるだけである.
下の例ではz2が録音されたデータの列になっている.

注意すべき点は,秒単位ではタイミングがずれることである.タイミング関係は使用している環境や負荷によるかもしれない.
import numpy as np
import sounddevice as sd
import matplotlib.pyplot as plt

fs = 44100
fbase = 4000;
t = np.linspace(0, 44099, num=44100, endpoint=False);
z = 0.2 * np.sin(t * 2 * np.pi * (fbase)) + 0.2 * np.sin(t * 2 * np.pi * (fbase + 1)) + 0.2 * np.sin(t * 2 * np.pi * (fbase + 2)) + 0.2 * np.sin(t * 2 * np.pi * (fbase + 3));

z2 = sd.playrec(4 * z, fs, channels=1)#sd.rec(int(duration * fs), samplerate=fs, channels=1)
sd.wait()

sd.play(z2, fs);
# 表示
Fz = np.fft.fft(z2) / z2.shape[0] * 2; # 折り返すのでパワーが2分の1になっている.
Fz[0] = Fz[0] / 2; # 平均成分は折り返さない.
Fz_abs = np.abs(Fz);

freq = np.fft.fftfreq(len(z), d=1.0/fs);
tim = np.arange(0, z2.shape[0]) * 1.0 / fs;
plt.figure(1)
plt.subplot(211);
plt.plot(tim, z2);

plt.subplot(212);
plt.plot(freq, Fz_abs * 1e6);
plt.xlim([0, 20000])

plt.show();


 

参考: sounddeviceでPythonを使って録音する

≫ Read More

2019/07/21 コンピュータ   TakeMe
Tag:Python

熱電対の温度と電圧の変換式を作る2

前回の記事では温度から熱起電力を求める式と熱起電力から温度を求める関数を用意していたが,逆が遅い.

とりあえず多項式近似なら,
前回

import numpy as np
import scipy as scipy
from scipy.optimize import fmin
import matplotlib
import matplotlib.pyplot as plt
import time

def GetK_Type_T2E(t):
    return -17.600413686 + 38.921204975 * t + 0.018558770032 * t ** 2 \
        + -0.000099457592874 * t ** 3  + 0.00000031840945719 * t ** 4 \
        + -5.6072844889E-10 * t ** 5 + 5.6075059059E-13 * t ** 6 \
        + -3.2020720003E-16 * t ** 7 + 9.7151147152E-20 * t ** 8 \
        + -1.2104721275E-23 * t ** 9 \
        + 118.5976 * np.exp(-0.0001183432 * (t - 126.9686) ** 2);

def f(t, *args):
    return np.abs(GetK_Type_T2E(t) - args[0])

def GetK_Type_E2T(e):
    t = e / 38.921204975;
    res  = scipy.optimize.minimize_scalar(f, bracket=None, bounds=(t - 0.7, t + 0.7), args=(e), method='brent', tol=1e-10);
    #res  = scipy.optimize.minimize_scalar(f, bracket=None, bounds=(t - 0.7, t + 0.7), args=(e), method='golden', options={'xtol': 1e-15});
    print(res)
    return res.x;

if __name__ == '__main__':
    start = time.time()
    t = 20
    e = GetK_Type_T2E(t);
    print(t)
    e0 = GetK_Type_T2E(20)
    print(e0)
    t0 = GetK_Type_E2T(e0)
    print(t0)
    elapsed_time = time.time() - start
    print ("elapsed: {0}".format(elapsed_time) + " s")

今回

import numpy as np
import scipy as scipy
from scipy.optimize import fmin
import matplotlib
import matplotlib.pyplot as plt
import time

def GetK_Type_T2E(t):
    return -17.600413686 + 38.921204975 * t + 0.018558770032 * t ** 2 \
        + -0.000099457592874 * t ** 3  + 0.00000031840945719 * t ** 4 \
        + -5.6072844889E-10 * t ** 5 + 5.6075059059E-13 * t ** 6 \
        + -3.2020720003E-16 * t ** 7 + 9.7151147152E-20 * t ** 8 \
        + -1.2104721275E-23 * t ** 9 \
        + 118.5976 * np.exp(-0.0001183432 * (t - 126.9686) ** 2);

def GetK_Type_E2T(e):
    global w;
    return np.polyval(w, e);

if __name__ == '__main__':
    start = time.time()
    ts = np.linspace(-40, 240, num=2801);
    es = GetK_Type_T2E(ts);
    
    w = np.polyfit(es, ts, 18)
    pvts = np.polyval(w, es)

    elapsed_time = time.time() - start
    print ("elapsed: {0}".format(elapsed_time) + " s")
    
今回の方が2801点計算しているのに同じ程度の時間で処理できている.

≫ Read More

2019/04/11 コンピュータ   TakeMe
Tag:Python

熱電対の温度と電圧の変換式を作る

JIS C1602 熱電対 に熱起電力の多項式近似が載っているのでそれをもとに温度-起電力の変換式を用意した.

Pythonで書いてみた.
(数値の一部桁はわざと変えてある.可能性がある)細かい数値はJISを参照していただくとして,...
変換関数自体は問題ないのだが,逆関数は載っていない.
一応 数値最適化を用いて逆関数を作ってみた.
中に,numpyを入れたのはまずかったかもしれない.

import numpy as np
import scipy as scipy
from scipy.optimize import fmin

def GetK_Type_T2E(t):
    return -17.600413686 + 38.921204975 * t + 0.018558770032 * t ** 2 \
        + -0.000099457592874 * t ** 3  + 0.00000031840945719 * t ** 4 \
        + -5.6072844889E-10 * t ** 5 + 5.6075059059E-13 * t ** 6 \
        + -3.2020720003E-16 * t ** 7 + 9.7151147152E-20 * t ** 8 \
        + -1.2104721275E-23 * t ** 9 \
        + 118.5976 * np.exp(-0.0001183432 * (t - 126.9686) ** 2);

def f(t, *args):
    return np.abs(GetK_Type_T2E(t) - args[0])

def GetK_Type_E2T(e):
    t = e / 38.921204975;
    res  = scipy.optimize.minimize_scalar(f, bracket=None, bounds=(t - 0.7, t + 0.7), args=(e), method='brent', tol=1e-10);
    #print(res)
    return res.x;

if __name__ == '__main__':

    t = 20
    e = GetK_Type_T2E(t);
    print(t)
    e0 = GetK_Type_T2E(20)
    print(e0)
    t0 = GetK_Type_E2T(e0)
    print(t0)

このやり方だと逆関数の計算が順方向の数十倍負荷がかかってしまう. もっと時間がかかるが,以下のようにした方がずれが小さくなる(かも).

res  = scipy.optimize.minimize_scalar(f, bracket=None, bounds=(t - 0.7, t + 0.7), args=(e), method='golden', options={'xtol': 1e-15});

≫ Read More

2019/04/06 コンピュータ   TakeMe
Tag:Python

C#からPythonの関数を呼び出し3

前のC#からのPythonの呼び出しの記事から新たに気が付いたことがあったので備忘録も含めて記載する.

使用するのはPython for .NETである.

git clone https://github.com/pythonnet/pythonnet.git

でgithubからpythonnetをダウンロードする.前にも述べている通りPythonの最新版は更新が速くてNugetパッケージは更新が追い付いていない.
ダウンロードされたフォルダの中にpythonnet.slnファイルがあるはずなのでこれを開き(Visual Studio 2017).
その後,ビルドの構成はReleaseWinPY3でx64(実際には実行環境に合わせる)でビルドする.するとbinフォルダにPython.Runtime.dllが出来上がる.

今回は呼び出した先のPythonのコードでmultiprocessingを使ってみた.
すると,Pythonで書かれている部分だけでなく.NET Frameworkで動いているプロセス全体が複製される.
C#から呼び出す先でマルチプロセスを使いたい場合には,プロセス全体が複製されることを前提に書いておく必要がある(複製された先からQueueなどの処理を行って処理を返さないと呼び出し元のプロセスはいつまでも待つ(特別な処理を書いていれば別だが)).

意図しない動作をしないように十分に注意する必要がある.

≫ Read More

2019/03/28 コンピュータ   TakeMe
Tag:Python