在C#和Python之间进行通信

3

我在C#和Python之间的通信上遇到了一些问题。

我正在使用以下的hacky代码将一些参数从C#传递给Python:

    string path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase).Substring(6);
    string pyUnintelligibilityPath = "\\unintelligibility.py";
    string pyNeuralPredictorPath = "\\predict.py";
    string clf = "\\clf.pkl";

    public double unintelligibleProbability(string pyLocation, string msg)
    {
        FileStream tempMessage = new FileStream(path + "\\tempMessage.txt", FileMode.Create);
        StreamWriter writer = new StreamWriter(tempMessage);
        writer.WriteLine(msg);
        writer.Close();

        string args = path + pyUnintelligibilityPath + " " + path + clf + " " + path + "\\tempMessage.txt" + " " + path + "\\tempCoefficient.txt";
        ProcessStartInfo start = new ProcessStartInfo();
        start.FileName = pyLocation;
        start.Arguments = args;
        start.UseShellExecute = false;
        start.RedirectStandardOutput = false;
        start.RedirectStandardError = false;
        Process process = Process.Start(start);
        Thread.Sleep(5000);
        double unintelligibility = Convert.ToDouble(File.ReadAllText(path + "\\tempCoefficient.txt").Replace('.', ','));

        return unintelligibility;
    }

很遗憾,在我的情况下,这种解决方案非常低效(甚至不是因为我没有代码检查文件是否更改,因为稍后将添加它而且不是真正的问题)。

问题在于,Python代码加载.pkl文件需要非常长的时间,然后才能做出有用的事情(不要介意不必要的导入,我只是从其他文件中重用了这个东西):

from sklearn.feature_extraction.text import TfidfTransformer, CountVectorizer, TfidfVectorizer
from sklearn.linear_model import LogisticRegression, SGDClassifier
from sklearn.svm import LinearSVC
from sklearn.cross_validation import cross_val_score
from sklearn.pipeline import Pipeline
from sklearn.decomposition import NMF, TruncatedSVD
from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier
from sklearn.pipeline import FeatureUnion
from sklearn.externals import joblib
import numpy as np
import pandas as pd
import codecs
import sys

clf = joblib.load(sys.argv[1])

data = codecs.open(sys.argv[2], encoding='utf-8', mode='r')
text = data.readlines()
data.close()
text = [x.strip() for x in text] 

f = open(sys.argv[3], mode='w')

proba = clf.predict_proba(text)
for i in range(0, len(text)):
    meme = proba[i,:]
    memeNum = meme[1]/(meme[0]+meme[1])
    f.write(str(memeNum.round(4)) + "\n")
f.close()

我的问题是,是否有可能以一种方式重新编写代码,使我可以在后台运行Python脚本,而C#只是向它传递命令,因为每次需要处理单个消息时重新初始化脚本太耗时了。
请注意,我真的不想使用任何基于网络协议的解决方案,因为这会使事情变得过于复杂,甚至不值得我这样做。我真的不关心远程执行或其他类似的事情,所有操作都在本地进行。但是,如果这是唯一的选择,那么我想我别无选择。

很遗憾您不想使用基于网络的解决方案。套接字似乎是一个好主意。如果数据不太复杂,这可以相当快地实现。 - Moritz Schmidt
数据只是字符串,可能包含长度从1到500个字符的UTF-8字符。 - ShadArt
我会建议你尝试使用TCP套接字。 - Moritz Schmidt
除了基于网络的协议之外,还有针对IPC的特定于操作系统的协议;如果您不介意使用中间件,消息队列(例如ZeroMQ)提供了一种轻松设置的方式。 (尽管例如ZeroMQ不支持Windows上的IPC,但在回环上的TCP将完全相同,除非它不符合您无网络协议的标准。) - fuglede
如果使用TCP确实是最简单的解决方案,我可能会尝试一下,那么我应该在哪里查找有关如何做到这一点的信息? - ShadArt
1个回答

0
尝试使用IronPython,它是一个 .Net - Python 桥接器。基本上你可以从 Python 访问 .net 的东西,或者从 C# 解释 Python。

如果我使用像scikit-learn这样的库,我会遇到兼容性问题吗? - ShadArt
我不确定,我猜最好的方式是尝试一下。 顺便提一下,我可以推荐你这个页面 https://wiki.python.org/moin/IntegratingPythonWithOtherLanguages - 2gJava
据我所知,IronPython仅支持Python 2.x版本。 - Kuku

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接