我想从 sys.stdin 读取两个不同的文件,我可以读取和写入文件,但第一个和第二个文件没有分离。
当我在 Windows 10 和 Python 3.6 中的 cmd 上运行以下代码时:
D:\digit>cat s.csv s2.csv
结果是:
1 2 3 4 5 1 2 3 4 5 6 7
我可以打印这两个文件。
我的Python代码是:
import sys
import numpy as np
train=[]
test=[]
#Assume below code is function 1 which just and must read s.csv
reader = sys.stdin.readlines()
for row in reader:
train.append(int(row[0]))
train = np.array(train)
print(train)
#I need some thing here to make separation
#sys.stdin.close()
#sys.stdin = sys.__stdin__
#sys.stdout.flush()
#Assume below code is function 2 which just and must read s2.csv
reader = sys.stdin.readlines()
for row in reader:
test.append(int(row[0]))
test = np.array(test)
print(test)
我在 cmd 提示符下运行以下命令:
D:\digit>cat s.csv s2.csv | python pytest.py
结果是:
[1 2 3 4 5 1 2 3 4 5 6 7]
[]
我需要为下一个文件重置 sys.stdin 吗?我使用了下面的,但没有一个是答案:
sys.stdin.close()
sys.stdin = sys.__stdin__
sys.stdout.flush()
让我尝试解释一下。
d:\digit>cat s.csv s2.csv
只有 1 个输出,而不是 2 个。它的作用是将
file1
的内容“流”到 stdout
,然后将 file2
的内容“流”到 stdout
,没有任何暂停或分隔符!
因此只有 1 个输出“流”,然后您可以使用 | 进行重定向。到你的 pyton 脚本:
| pytest.py
因此
pytest.py
将接收 1 个输入“流”,它不知道更好或更多。
如果您想通过
pytest.py
单独处理文件,您可以执行以下操作
D:\digit>cat s.csv | python pytest.py # process the first file
D:\digit>cat s2.csv | python pytest.py # process the second file
或单线:
D:\digit>cat s.csv | python pytest.py && cat s2.csv | python pytest.py
请记住,
pytest.py
实际上正在运行两次。所以你需要为此调整你的 python 脚本。
但是当你编辑 python 脚本时...
你应该做什么: 如果您希望这两个文件都在您的
pytest.py
中,那么您应该编写一些代码来读取 python 脚本中的这两个文件。如果是 csv 结构化数据,那么看看 csv 模块用于读写 csv 文件
[根据评论编辑:]
我可以通过 pandas "pd.read_csv" 读取多个文件,但是我的 问题是我该如何通过 sys.stdin 来做到这一点?
您真的应该质疑为什么您如此专注于使用
stdin
。从 python 脚本中读取它可能会更有效。
如果您必须使用
stdin
,那么您可以部署各种但在Python外部的页眉、页脚、分隔符。一旦定义了这个并且能够执行此操作,您就可以更改 python 中的代码来执行各种功能,具体取决于从 stdin
接收到的页眉/页脚/分隔符。
这一切听起来有点复杂并且容易出错。我强烈建议您重新考虑使用 stdin 作为脚本的输入。或者,请使用您面临的技术要求和限制来更新您的问题,这些要求和限制限制您使用标准输入。
[根据评论编辑:]
我想在 Hadoop 生态系统中加载这些文件并且我正在使用 Hadoop 流媒体为此
不知何故,您需要向您的 python 脚本发出“信号”,表明它正在处理带有新信息的新文件。
假设您有 2 个文件,第一行需要是某种指示文件的“标头”,以及需要对其余数据执行哪个函数,直到收到新的“标头”。
所以可以说,您的“训练”数据以行
@is_train@
为前缀,而您的“测试”数据以行 @is_test@
为前缀
如何在您的环境中做到这一点,不属于此问题的范围
现在重定向到标准输入将在数据之前发送这两个标头。你可以使用 python 来检查这些,例如:
import sys
import numpy as np
train=[]
test=[]
is_train = False
is_test = False
while True:
line = sys.stdin.readline()
if '@stop@' in line:
break
if '@is_train@' in line:
is_train = True
is_test = False
continue
if '@is_test@' in line:
is_train = False
is_test = True
continue
#if this is csv data, you might want to split on ,
line = line.split(',')
if is_train:
train.append(int(line[0]))
if is_test:
test.append(int(line[0]))
test = np.array(test)
train = np.array(train)
print(train)
print(test)
正如您在代码中看到的,您还需要一个“页脚”来确定数据何时结束,在本例中选择了
@stop@
。
发送页眉/页脚的一种方法可能是:
D:\digit>cat is_train.txt s.csv is_test.txt s2.csv stop.txt | python pytest.py
以及三个额外文件,仅包含适当的页眉或页脚
另一个解决方案是:
import sys
train=[]
args = sys.stdin.readlines()[0].replace("\"", "").split()
for arg in args:
arg=arg.strip()
with open(arg, "r") as f:
train=[]
for line in f:
train.append(int(line))
print(train)
s.txt 是:
1
2
3
s2.txt 是:
7
8
9
D:\digit>echo s.txt s2.txt | python argpy.py
[1, 2, 3]
[7, 8, 9]
关键有两点:
使用 echo 代替 cat 以防止串联 更多学习链接:‘猫’之间的区别< file.txt' and 'echo < file.txt'
尝试通过拆分每个文件并存储在 args 中来读取每个新文件的 for 循环。 如何使用 sys.stdin 作为多个文本文件的输入来运行代码
快乐,因为我已经做到了:)