为 for 循环内的行赋值 python
Assign value to rows inside a for loop python
我不明白为什么我的下面的代码不会为 for 循环内的第 n 行分配一个新值。据我所知,我索引 b 矩阵的方式应该是正确的,但似乎 count 变量不会在每次迭代时更新。
打印语句仅用作检查正在发生的事情的一种方式。
我认为这很简单,所以如果有人能指出我的错误,我将不胜感激。
#!/usr/bin/python
import sys
#from string import maketrans
#import re
import numpy as np
lines = sum(1 for line in sys.stdin)
b = np.zeros((lines,2))
count = 0
for line in sys.stdin:
line = line.strip()
myline = line.split(",")
Depart = myline[3]
DepartDelay = float(myline[6])
if DepartDelay<0:
DepartDelay=0
b[count,0] = Depart
b[count, 1] = DepartDelay
count = count + 1
print(count)
print(b)
print(count)
我使用以下命令在 Ubuntu 的终端内执行代码。
cat sample.txt | mapper.py
这就是为什么没有指定任何 data/text 文件的原因。
提前,谢谢!
sys.stdin
基本上是一个文件对象,所以我的意见是不要做类似 for line in sys.stdin
的事情(它在技术上可能有效,但它的形式不好。另外,你还有其他问题,所有提前)
我更愿意在 sys.stdin 上调用 read()
或 readlines()
方法来阅读内容
在此处熟悉标准输入的基础知识:How do you read from stdin in Python?
适合您的循环应该如下所示:
lines = sys.stdin.readlines()
for line in lines:
do_something(line)
但要小心,如果您在程序开始时遍历整个标准输入(当您这样做时 lines = sum(1 for line in sys.stdin)
),您不能简单地再次开始迭代
一个更简单的方法是阅读上面提到的所有行,但如果您需要行的长度,您可以先这样做:
count_lines = len(lines)
总而言之,您的程序的开头应该是这样的:
lines = sys.stdin.readlines()
b = []
count = 0
for line in lines:
Depart, DepartDelay = do_something(line)
b.append([Depart, DepartDelay])
编辑:我根本不会使用 numpy 来解决这样一个简单的问题,要存储多种类型(浮点数和字符串)
核心问题似乎是您从 sys.stdin
读取了两次。一旦进入 sum
的参数,它将读取整个输入,然后再次进入 for 循环。因为文件有一个当前位置,所以通常的结果是 for 循环没有要处理的东西。 stdin 也可能是一个流,所以不能倒带。您必须只加载一次数据。
第二个问题是您是否可以使用更高的抽象级别加载数据。看起来您正在阅读 CSV,csv.reader
might be useful, but it's collected in a numpy array, which makes numpy.loadtxt
更吸引人。它甚至有一个 usecols
字段来读取特定的列。
count
变量也可以更容易地处理,使用 for count, line in enumerate(sys.stdin):
。这将随着行的读取而增加它。
我认为一个不错的起点是这样的:
b = np.loadtxt(sys.stdin, delimiter=',', usecols=(3,6))
b[:,1] = np.maximum(b[:,1], 0) # Set no lower than 0
我不明白为什么我的下面的代码不会为 for 循环内的第 n 行分配一个新值。据我所知,我索引 b 矩阵的方式应该是正确的,但似乎 count 变量不会在每次迭代时更新。 打印语句仅用作检查正在发生的事情的一种方式。
我认为这很简单,所以如果有人能指出我的错误,我将不胜感激。
#!/usr/bin/python
import sys
#from string import maketrans
#import re
import numpy as np
lines = sum(1 for line in sys.stdin)
b = np.zeros((lines,2))
count = 0
for line in sys.stdin:
line = line.strip()
myline = line.split(",")
Depart = myline[3]
DepartDelay = float(myline[6])
if DepartDelay<0:
DepartDelay=0
b[count,0] = Depart
b[count, 1] = DepartDelay
count = count + 1
print(count)
print(b)
print(count)
我使用以下命令在 Ubuntu 的终端内执行代码。
cat sample.txt | mapper.py
这就是为什么没有指定任何 data/text 文件的原因。
提前,谢谢!
sys.stdin
基本上是一个文件对象,所以我的意见是不要做类似 for line in sys.stdin
的事情(它在技术上可能有效,但它的形式不好。另外,你还有其他问题,所有提前)
我更愿意在 sys.stdin 上调用 read()
或 readlines()
方法来阅读内容
在此处熟悉标准输入的基础知识:How do you read from stdin in Python?
适合您的循环应该如下所示:
lines = sys.stdin.readlines()
for line in lines:
do_something(line)
但要小心,如果您在程序开始时遍历整个标准输入(当您这样做时 lines = sum(1 for line in sys.stdin)
),您不能简单地再次开始迭代
一个更简单的方法是阅读上面提到的所有行,但如果您需要行的长度,您可以先这样做:
count_lines = len(lines)
总而言之,您的程序的开头应该是这样的:
lines = sys.stdin.readlines()
b = []
count = 0
for line in lines:
Depart, DepartDelay = do_something(line)
b.append([Depart, DepartDelay])
编辑:我根本不会使用 numpy 来解决这样一个简单的问题,要存储多种类型(浮点数和字符串)
核心问题似乎是您从 sys.stdin
读取了两次。一旦进入 sum
的参数,它将读取整个输入,然后再次进入 for 循环。因为文件有一个当前位置,所以通常的结果是 for 循环没有要处理的东西。 stdin 也可能是一个流,所以不能倒带。您必须只加载一次数据。
第二个问题是您是否可以使用更高的抽象级别加载数据。看起来您正在阅读 CSV,csv.reader
might be useful, but it's collected in a numpy array, which makes numpy.loadtxt
更吸引人。它甚至有一个 usecols
字段来读取特定的列。
count
变量也可以更容易地处理,使用 for count, line in enumerate(sys.stdin):
。这将随着行的读取而增加它。
我认为一个不错的起点是这样的:
b = np.loadtxt(sys.stdin, delimiter=',', usecols=(3,6))
b[:,1] = np.maximum(b[:,1], 0) # Set no lower than 0