我正在使用ffmpeg的extract_mvs文件来生成一些文本信息。我会在终端中使用这样的命令:
/extract_mvs input.mp4 > output.txt
我想将此命令与
Popen
或 python 中的其他子进程一起使用,以便将数据直接传递到 pandas 数据框而不实际生成文本文件,而不是 output.txt。
这个想法是多次自动执行此操作,因此,我试图避免生成许多 .txt 文件,从而必须将它们一一进行
open()
。
我想到了这样的事情:
import subprocess
cmd = ['./extract_mvs', 'input.mp4']
a = subprocess.Popen(cmd, stdout=subprocess.PIPE)
df = pd.read_csv(a.communicate()[0], sep=',')
但随后我收到错误:
OSError: Expected file path name or file-like object, got <class 'bytes'> type
可以修复和扩展它,以便直接从子进程读取到pandas吗?
我找到了一种解决方法,使用 Keith 的部分答案和在此处找到的答案 ,将信息从字符串传递到 pandas 数据帧。
最终的工作代码是:
import sys
import subprocess
import pandas as pd
cmd = ['./extract_mvs', 'input.mp4']
a = subprocess.Popen(cmd, stdout=subprocess.PIPE)
if sys.version_info[0] < 3:
from StringIO import StringIO
else:
from io import StringIO
b = StringIO(a.communicate()[0].decode('utf-8'))
df = pd.read_csv(b, sep=",")
我对你的问题和我建议的第一个答案的输出思考得越多,我就越认为你的问题不是解码问题,也许更多的是未能向
pd.read_csv()
提供正确的输入。作为替代方案,您可以尝试完全跳过 pd.read_csv()
。相反,您可以尝试将子流程的输出逐行读取到数据帧中。
类似这样的:
cmd = ['./extract_mvs', 'input.mp4']
df = pd.DataFrame()
a = subprocess.Popen(cmd, stdout=subprocess.PIPE)
for line in a.stdout:
df = pd.concat([df, line])
a.wait()
同样,我自己还没有测试过这段代码(因为我现在正在旅行并使用我的手机),但我希望这能让您更接近解决方案。
我还没有对此进行测试,但我认为您只需要解码子进程执行返回的结果即可。具体来说,您需要将结果从
bytes
解码为 utf-8
。
您可以尝试:
pd.read_csv(a.communicate()[0].decode('utf-8'))
import os
import subprocess
import pandas as pd
import sys
cmd = 'NSLOOKUP email.fullcontact.com'
df = pd.DataFrame()
a = subprocess.Popen(cmd, stdout=subprocess.PIPE)
if sys.version_info[0] < 3:
from StringIO import StringIO
else:
from io import StringIO
b = StringIO(a.communicate()[0].decode('utf-8'))
df = pd.read_csv(b, sep=",")
column = list(df.columns)
name = list(df.iloc[1])[0].strip('Name:').strip()
name
import subprocess
import pandas as pd
cmd = ['./extract_mvs', 'input.mp4']
p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
df = pd.read_csv(p.stdout)
if p.wait() != 0:
raise Exception(f"Command exited with {p.returncode}")
此代码在生成输出时构建数据帧。对于具有大量输出的长时间运行的程序,它将避免在使用
read_csv
处理之前将整个输出缓冲在内存中,这可能会显着减少程序的内存占用。
在此代码片段中,
p.stdout
是一个可读的流对象(也称为类似文件的对象)。