【发布时间】:2016-02-08 17:17:16
【问题描述】:
我正在尝试使用第一个文件中的信息编辑 CSV 文件。这对我来说似乎并不简单,因为我应该过滤多个东西。让我们解释一下我的问题。
我有两个 CSV 文件,比如说 patch.csv 和 origin.csv。输出 csv 文件应与 origin.csv 具有相同的模式,但具有更正的值。
如果origin.csv 行中的direction_id 字段为0,我想使用patch.csv 中的forward_line_name 列替换origin.csv 中的trip_headsign 列字段,或者如果direction_id 为1,则使用backward_line_name。
只有当 patch.csv 中“:”和“:”符号之间的 line_id 值部分与 origin.csv 中“:”符号之前的 route_id 值部分相同时,我才想这样做。
我知道如何替换整行,但不仅是某些部分,尤其是有时我只需要查看值的一部分。
这是 origin.csv 的示例:
route_id,service_id,trip_id,trip_headsign,direction_id,block_id
210210109:001,2913,70405957139549,70405957,0,
210210109:001,2916,70405961139553,70405961,1,
还有一个 patch.csv 样本:
line_id,line_code,line_name,forward_line_name,forward_direction,backward_line_name,backward_direction,line_color,line_sort,network_id,commercial_mode_id,contributor_id,geometry_id,line_opening_time,line_closing_time
OIF:100110010:10OIF439,10,Boulogne Pont de Saint-Cloud - Gare d'Austerlitz,BOULOGNE / PONT DE ST CLOUD - GARE D'AUSTERLITZ,OIF:SA:8754700,GARE D'AUSTERLITZ - BOULOGNE / PONT DE ST CLOUD,OIF:SA:59400,DFB039,91,OIF:439,metro,OIF,geometry:line:100110010:10,05:30:00,25:47:00
OIF:210210109:001OIF30,001,FFOURCHES LONGUEVILLE PROVINS,Place Mérot - GARE DE LONGUEVILLE,,GARE DE LONGUEVILLE - Place Mérot,OIF:SA:63:49,000000 1,OIF:30,bus,OIF,,05:39:00,19:50:00
每个文件都有数百行我需要以这种方式解析和编辑。
根据 mhopeng 的回答,我得到了那个代码:
#!/usr/bin/env python2
from __future__ import print_function
import fileinput
import sys
# first get the route info from patch.csv
f = open(sys.argv[1])
d = open(sys.argv[2])
# ignore header line
#line1 = f.readline()
#line2 = d.readline()
# get line of data
for line1 in f.readline():
line1 = f.readline().split(',')
route_id = line1[0].split(':')[1] # '210210109'
route_forward = line1[3]
route_backward = line1[5]
line_code = line1[1]
# process origin.csv and replace lines in-place
for line in fileinput.input(sys.argv[2], inplace=1):
line2 = d.readline().split(',')
num_route = line2[0].split(':')[0]
# prevent lines with same route_id but different code to be considered as the same line
if line.startswith(route_id) and (num_route == line_code):
if line.startswith(route_id):
newline = line.split(',')
if newline[4] == 0:
newline[3] = route_backward
else:
newline[3] = route_forward
print('\t'.join(newline),end="")
else:
print(line,end="")
但不幸的是,这不会在trip_headsign(总是向前)中推动正确的向前或向后的线名,并最终在完成文件解析之前触发该错误:
Traceback(最近一次调用最后一次): 文件“./GTFS_enhancer_headsigns.py”,第 28 行,在 如果换行[4] == 0: IndexError: 列表索引超出范围
感谢您对此的帮助。
【问题讨论】:
-
如果您编辑问题以包含两个输入 csv 文件的示例以及输出 csv 文件的外观,将会有所帮助。
-
刚刚使用来自两个 csv 文件的样本进行了编辑,这里我要比较的 line_id 部分是 100110010,我想将它与 210210109 route_id 部分进行比较。如果两者相同,我想执行更改。
-
你确定标题行和标题后的空白行没有引起问题吗?如果您正在读取空行,则换行符[4] 将不存在。
-
原始示例文件 sn-ps 也是制表符分隔的(并且在标题后没有此空白行)。所以别忘了把所有的
'\t'改成','。 -
您的代码看起来像是将一个文件的每一行与另一个文件中的一行(具有相同行号的行)进行比较。这是你的意图吗?如果是这样,这在问题陈述中并不明显。或者patch.csv中的任何一行都可以用来修改origin.csv中的任何一行吗?