这是我之前提出的问题。 感谢很多人,我可以修改我的代码如下。
import csv
with open("SURFACE2", "rb") as infile, open("output.txt", "wb") as outfile:
reader = csv.reader(infile, delimiter=" ")
writer = csv.writer(outfile, delimiter=" ")
for row in reader:
row[18] = "999"
writer.writerow(row)
我只是更改" \ t"的分隔符到" &#34 ;.具有先前分隔符的Whiel,代码仅用于行[0],其中" "代码可以工作到行[18]。
15.20000 120.60000 98327 get data information here. SURFACE DATA FROM ??????????? SOURCE FM-12 SYNOP 155.00000 1 0 0 0 0 T F F -888888 -888888 20020601030000 100820.00000
从上面的数据行,第[18]行正好在15.20000和120.60000之间。
我不确定这两个值之间会发生什么。可能是分隔符更改?但在视觉上我无法发现任何差异。 有什么方法可以让我知道分隔符已经改变了吗?如果有的话,你有没有想过为一个代码处理多个分隔符?
任何想法或帮助都会非常感激。
谢谢你, 艾萨克
repr的结果(下一个(infile)):
' 15.20000 120.60000 98327 get data information here. SURFACE DATA FROM ??????????? SOURCE FM-12 SYNOP 155.00000 1 0 0 0 0 T F F -888888 -888888 20020601030000 100820.00000 0-888888.00000 0-888888.00000 0-888888.00000 0-888888.00000 0-888888.00000 0-888888.00000 0-888888.00000 0-888888.00000 0-888888.00000 0-888888.00000 0-888888.00000 0-888888.00000 0\n'
' 99070.00000 0 155.00000 0 303.20001 0 297.79999 0 3.00000 0 140.00000 0-888888.00000 0-888888.00000 0-888888.00000 0-888888.00000 0\n'
'-777777.00000 0-777777.00000 0 1.00000 0-888888.00000 0-888888.00000 0-888888.00000 0-888888.00000 0-888888.00000 0-888888.00000 0-888888.00000 0\n'
' 1 0 0\n'
' 55.10000 -3.60000 03154 get data information here. SURFACE DATA FROM ??????????? SOURCE FM-12 SYNOP 16.00000 1 0 0 0 0 T F F -888888 -888888 20020601030000-888888.00000 0-888888.00000 0-888888.00000 0-888888.00000 0-888888.00000 0-888888.00000 0-888888.00000 0-888888.00000 0-888888.00000 0-888888.00000 0-888888.00000 0-888888.00000 0-888888.00000 0\n'
'-888888.00000 0 16.00000 0 281.20001 0 279.89999 0 0.00000 0 0.00000 0-888888.00000 0-888888.00000 0-888888.00000 0-888888.00000 0\n'
'-777777.00000 0-777777.00000 0 1.00000 0-888888.00000 0-888888.00000 0-888888.00000 0-888888.00000 0-888888.00000 0-888888.00000 0-888888.00000 0\n'
' 1 0 0\n'
正如您所看到的,实际上四条第一行应该是一条线。由于某种原因,全线似乎分为4部分。 你有什么主意吗? 谢谢, 艾萨克
答案 0 :(得分:2)
N.B。此document的第19页讨论了文件格式。这或多或少与样本数据一致。
修改强>
好的,在考虑了各种评论,其他答案以及阅读original question后,似乎所讨论的文件不是CSV文件。天气观测数据格式为" little_r"它使用用空格填充的固定宽度字段。没有太多可用的信息,所以我猜测,但每组4行似乎包含一个观察。从您之前的问题看,您似乎想要更新第一行的第3列?其他3行将被跳过。然后更新下一组4行等的第一行中的第3列,等等。
OP的一个例子:
15.20000 120.60000 98327 get data information here. SURFACE DATA FROM ??????????? SOURCE FM-12 SYNOP 155.00000 1 0 0 0 0 T F F -888888 -888888 20020601030000 100820.00000 0-888888.00000 0-888888.00000 0-888888.00000 0-888888.00000 0-888888.00000 0-888888.00000 0-888888.00000 0-888888.00000 0-888888.00000 0-888888.00000 0-888888.00000 0-888888.00000 0 99070.00000 0 155.00000 0 303.20001 0 297.79999 0 3.00000 0 140.00000 0-888888.00000 0-888888.00000 0-888888.00000 0-888888.00000 0 -777777.00000 0-777777.00000 0 1.00000 0-888888.00000 0-888888.00000 0-888888.00000 0-888888.00000 0-888888.00000 0-888888.00000 0-888888.00000 0 1 0 0
第一行的前两列是(我猜测)观察的纬度和经度。我不知道第3列98327
是什么,但这是OP想要更新的列(基于之前的问题)。
它不是CSV文件,因此不要将其作为一个文件进行处理。相反,因为有固定的宽度字段,我们知道需要更新的字段的偏移量和宽度。基于样本数据,第3列占据字符41-46。因此,要更新数据并写入新文件:
offset_col_3 = 41
length_col_3 = 5
with open('SURFACE2') as infile, open('output.txt', 'w') as outfile:
for line_no, line in enumerate(infile):
if line_no % 4 == 0: # every 4th line starting with the first
line = '{}{:>5}{}'.format(line[:offset_col_3], 999, line[offset_col_3+length_col_3:])
outfile.write(line)
原始回答
尝试从文件中读取第20行(行[19])(假设CSV文件中没有标题行,否则为第21行)并在Python中检查它:
with open("SURFACE2") as infile:
for i in range(20):
print repr(next(infile))
显示的最后一行是第18行。例如,如果制表符是分隔符,那么您可能会在数据列之间看到\t
。将前一行与最后一行进行比较,以查看所使用的分隔符是否存在差异。
如果您发现CSV文件是混合分隔符,则可能需要手动拆分字段。
答案 1 :(得分:1)
当您的文件中包含固定宽度字段时,csv
模块不是正确的工具。您需要做的是明确使用字段长度来分割线条。例如:
# This would be your whole file
data = "\n".join([
"abc def gh i",
"jk lm n o",
"p q r s",
])
field_widths = [5, 4, 3, 1]
def fields(line, field_widths):
pos = 0
for length in field_widths:
yield line[pos:pos + length].strip()
pos += length
for line in data.split("\n"):
print(list(fields(line, field_widths)))
会给你:
['abc', 'def', 'gh', 'i']
['jk', 'lm', 'n', 'o']
['p', 'q', 'r', 's']