在不创建外部文本文件的情况下将终端输出捕获到 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
Wordpress:在不使用文本小部件的情况下将 html 代码添加到小部件区域