将pandas数据帧作为参数传递给Python子进程Popen

5
我正在尝试从主脚本调用一个Python脚本,需要在主脚本中生成一次数据帧,然后将其作为参数传递给子进程脚本,并在子进程中使用它。以下是我撰写的所需Python主脚本。
from subprocess import PIPE, Popen
import pandas as pd

test_dataframe = pd.read_excel(r'C:\test_location\file.xlsx',sheetname='Table')

sp = Popen(["python.exe",'C:/capture/test.py'], shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE)
sp.communicate(test_dataframe)

下面是错误信息:

TypeError: 参数1必须可转换为缓冲区,而不是DataFrame

这是我第一次尝试使用subprocess模块,所以我还不是很熟练。任何帮助将不胜感激。

2个回答

4

以下是Python 3.6的完整示例,演示主脚本和子进程之间的双向通信。

master.py

import pandas as pd
import pickle
import subprocess

df = pd.read_excel(r'C:\test_location\file.xlsx',sheetname='Table')

result = subprocess.run(['python', 'call_model.py'], input=pickle.dumps(df), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
returned_df = pickle.loads(result.stdout)
assert df == returned_df

如果出现问题,您可以检查result.stderr

subroutine.py

import pickle
import sys

data = pickle.loads(sys.stdin.buffer.read())
sys.stdout.buffer.write(pickle.dumps(data))

3

子进程启动另一个应用程序。进程之间通信的方式与Python程序内部函数通信的方式有很大不同。您需要通过非Python环境传递DataFrame。因此,您需要将其序列化为文本,然后在另一端反序列化。例如,您可以使用pickle模块,然后在一端使用sp.communicate(pickle.dumps(test_dataframe)),在另一端使用pickle.loads(sys.stdin.read())。或者您可以将DataFrame写入csv文件,然后再次解析它。或者您可以使用任何其他格式。


1
嗨Alex,谢谢你的回复。我尝试使用pickle,但在查看主脚本后,它自动关闭而没有给出任何错误,并且子进程脚本中的任何命令都没有运行。 - python_enthusiast
你确定子进程没有被执行吗?也许它已经被执行了,但你没有检查它是否成功完成了?同时检查一下进程的输出,它是通过sp.communicate返回的。此外,检查一下shell=True的作用。你正在将命令作为数组传递,但也指定了shell=True - Alexey Guseynov
1
我的子进程从一个打印命令开始,并以raw_input()结束,以便我可以看到它是否运行,弹出窗口在关闭之前不显示任何内容。我尝试使用和不使用shell,但无论哪种方式,我都没有从子进程中得到任何东西。我尝试运行时没有stdin、stdout和stderr,只有子进程的第一个打印命令才能运行,但会永远停留在pickle.loads(sys.stdin.read())处。 - python_enthusiast

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