在不创建外部文本文件的情况下将终端输出捕获到 pandas 数据帧中

Posted

技术标签:

【中文标题】在不创建外部文本文件的情况下将终端输出捕获到 pandas 数据帧中【英文标题】:Capturing terminal output into pandas dataframe without creating external text file 【发布时间】:2018-08-03 10:18:37 【问题描述】:

我正在使用 ffmpeg 的 extract_mvs 文件来生成一些文本信息。我会在终端中使用这样的命令:

/extract_mvs input.mp4 > output.txt

我想将此命令与Popen 或python 中的其他子进程一起使用,这样数据就可以直接传递到pandas 数据框而不是实际生成文本文件。

这个想法是多次自动执行此操作,因此,我试图避免生成许多 .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?

【问题讨论】:

【参考方案1】:
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

【讨论】:

请不要只留下代码作为答案。用英语解释你的代码做了什么,并解释为什么它是正确的答案。【参考方案2】:

更新答案:

我对您的问题和我建议的第一个答案的输出考虑得越多,我就越认为您的问题不是解码问题,而可能更多的是未能向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'))

【讨论】:

感谢您的意见。我猜这离解决方案更近了一步。当我尝试上述方法时,我得到:prntscr.com/iipcq6 它在控制台中打印信息,而它应该存储在 df 中。当调用 df 时,它说它没有定义。【参考方案3】:

我找到了一种解决方法,使用Keith 和found here 的部分答案,将信息从字符串传递到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=",")

【讨论】:

以上是关于在不创建外部文本文件的情况下将终端输出捕获到 pandas 数据帧中的主要内容,如果未能解决你的问题,请参考以下文章

ImageMagick:在不使用外部文本文件的情况下将选择性图像转换为多页 PDF?

如何在不损失视网膜显示质量的情况下将 UIView 捕获到 UIImage

text 如何在不中断的情况下将终端迁移到ZSH

Wordpress:在不使用文本小部件的情况下将 html 代码添加到小部件区域

如何在不写入磁盘的情况下将 AWS S3 上的文本文件导入 pandas

如何在不创建架构的情况下将 CSV 文件加载到 BigQuery