将终端输出捕获到 pandas 数据框中,而不创建外部文本文件

问题描述 投票:0回答:4

我正在使用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吗?

python pandas ffmpeg terminal popen
4个回答
8
投票

我找到了一种解决方法,使用 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=",")

3
投票

更新答案:

我对你的问题和我建议的第一个答案的输出思考得越多,我就越认为你的问题不是解码问题,也许更多的是未能向

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'))


0
投票
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

0
投票
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
是一个可读的流对象(也称为类似文件的对象)。

© www.soinside.com 2019 - 2024. All rights reserved.