Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
什么';在CSV中消除两个连续记录的重复数据并保留一个记录,这是最优雅的python方法吗?_Python_List_Csv_Duplicates - Fatal编程技术网

什么';在CSV中消除两个连续记录的重复数据并保留一个记录,这是最优雅的python方法吗?

什么';在CSV中消除两个连续记录的重复数据并保留一个记录,这是最优雅的python方法吗?,python,list,csv,duplicates,Python,List,Csv,Duplicates,我正在尝试删除CSV中的重复记录。我不认为自己是新的Python或者编写ETL脚本。我已经做了尽职调查并搜索了S.O.页面,不认为这个问题会被稀释到使用集合(就像大多数重复数据消除问题一样) 我的目标是:对于ORIG等于前一行ORIG的所有行,在ORIG等于的两行中,删除SEQ_TIME==0的行 正如Python的格言所说,“应该有一种——最好只有一种——显而易见的方法来做到这一点。”我已经编写了我认为可以实现这一点的代码,但任何人都会告诉你这是非常不符合Python的。CSV数据如下所示,下

我正在尝试删除CSV中的重复记录。我不认为自己是新的Python或者编写ETL脚本。我已经做了尽职调查并搜索了S.O.页面,不认为这个问题会被稀释到使用集合(就像大多数重复数据消除问题一样)

我的目标是:对于ORIG等于前一行ORIG的所有行,在ORIG等于的两行中,删除SEQ_TIME==0的行

正如Python的格言所说,“应该有一种——最好只有一种——显而易见的方法来做到这一点。”我已经编写了我认为可以实现这一点的代码,但任何人都会告诉你这是非常不符合Python的。CSV数据如下所示,下面是我的单独结果CSV。满足条件的行以黄色突出显示,以便于比较

数据作为CSV文本:

TRAIN#,SEQ#,ORIG,DEP,DEST,ARR,SEQ#u时间
A21,9,BPK,0.582986111,X66,0.584375,2
A21,10,X66,0.584375,CNLEMOYN,0.58680556,3.5
A21,11,CNLEMOYN,0.58680556,SMT,0.59097222,6
A21,12,SMT,0.59097222,0.59097222,0
A21,13,SMT,0.59097222,北运河,0.591666667,1
A21,14,CNCANNAL,0.591666667,MEWILSPR,0.594791667,4.5
A21,15,MEWILSPR,0.594791667,0.594791667,0
A21,16,MEWILSPR,0.594791667,MELEMONT,0.6,7.5
A21,17,梅勒蒙特,0.6,0.6,6.5
A21,18,MELEMONT,0.6,MELOCKPO,0.605208333,0
A21,19,MELOCKPO,0.605208333,0.605208333,0
A21,20,MELOCKPO,0.605208333,XUD,0.60625,2.5
A21,21,XUD,0.60625,JOL,0.607638889,2
下面是我认为能够实现目标的(非Pythonic)代码

导入csv
f=打开(“my_data.csv”、“r”)
reader=csv.reader(f,lineterminator=“\n”)
header=reader.next()
#听写理解,以便我们可以通过索引或名称引用每一列。
hdict={value:索引的索引,枚举(头)中的值}
#数据被转换成二维列表,因为我以后会用它做其他事情。
数据=[读卡器中的行对行]
#主(非肾盂)溶液。
结果=[]
尝试:
i=0
尽管如此:
第1行=数据[i]
row2=数据[i+1]#将导致最后一行出现索引器。
如果第1行[hdict[“原始”]==第2行[hdict[“原始”]:
如果浮动(第1行[hdict[“顺序时间”]):
result.append(第1行)
elif浮动(第2行[hdict[“顺序时间”]):
result.append(第2行)
其他:
raise AssertionError(“两个具有等效ORIG的连续行不能同时具有SEQ_TIME==0。”)
i+=1#Force在下一次迭代中跳到第3行,因为上面处理了第1行和第2行。
其他:
result.append(第1行)
i+=1#我正在使用手动索引强制执行循环。
除索引器外:
result.append(数据[-1])#处理最后一行。
#将结果写入其他CSV。
g=打开(“my_results.csv”、“w”)
writer=csv.writer(g,lineterminator=“\n”)
writer.writerow(标题)
对于结果中的行:
writer.writerow(结果)
f、 关闭()
g、 关闭()
虽然Python中的
while-True:break
习惯用法很常见,而且(我相信)编码也很草率,但是
try:while-True:go-forever:except-indexer
习惯用法确实很糟糕。是否有更简单、更优雅的方法来完成此任务,例如简单的
for
循环

我追求的一个想法是使用iterable来控制光标,因为它在
for
循环中遍历每一行:

data\u iterable=iter(数据)
对于数据表中的行:
行1=行[:]
row2=数据可编辑。next()#在此处控制光标。
如果第1行[hdict[“原始”]==第2行[hdict[“原始”]:
如果浮动(第1行[hdict[“顺序时间”]):
result.append(第1行)
其他:
result.append(第2行)
#可以省略AssertionError检查。
其他:
结果。追加(第1行)#如果没有异常。。。
结果.追加(第2行)#追加两行。
这里的问题是,此代码只处理偶数重复项,而忽略奇数重复项

或者,我们可以对数据进行两次迭代,根据一些ID(如SEQ)标记要保留在
keep_这些行
列表中的行。然后在第二次传递时,仅将这些行附加到结果?但在我看来,这似乎同样笨拙,必要时慢了两倍

人群中有更好的解决方案吗

注意事项:

  • hdict
    是一种结合
    csv.reader
    csv.DictReader
    功能的简单方法,因此您可以按名称引用行,例如
    row[hdict[“ORIG]”]
    或索引,例如
    row[2]
  • 我读了@DSM的一篇文章,其中提到了作为竞争者的功能。这对我们有好处吗

谢谢

如果要压缩的组都是连续的,那么
itertools.groupby
可能很有用。假设(比如)我们希望保留SEQ_TIME==0个案例,如果它们是组中唯一的成员,或者如果有三个SEQ_TIME==0的连续条目,我们可以执行类似(Python 3 csv开放式)的操作:

这让我

TRAIN#,SEQ#,ORIG,DEP,DEST,ARR,SEQ_TIME
A21,9,BPK,0.582986111,X66,0.584375,2
A21,10,X66,0.584375,CNLEMOYN,0.586805556,3.5
A21,11,CNLEMOYN,0.586805556,SMT,0.590972222,6
A21,13,SMT,0.590972222,CNCANAL,0.591666667,1
A21,14,CNCANAL,0.591666667,MEWILSPR,0.594791667,4.5
A21,16,MEWILSPR,0.594791667,MELEMONT,0.6,7.5
A21,17,MELEMONT,0.6,,0.6,6.5
A21,20,MELOCKPO,0.605208333,XUD,0.60625,2.5
A21,21,XUD,0.60625,JOL,0.607638889,2

可以根据需要调整组条件。如果您知道永远不会有任何SEQ_TIME=0案例需要保留,代码可能会变得更简单,但这应该给您一个开始的地方。

为什么要发布图像而不是文本?这更适合codereview.stackexchange。com@DSM添加CSV作为文本,并在itertools.groupby帖子中提到您的名字。谢谢。@chepner我想你是对的。我不会在codereview.stackexchange.com的董事会上重新发布这篇文章,因为我担心来自不同成员的“双海报”报复,但是如果有人可以点击这篇文章,请尽一切努力。
TRAIN#,SEQ#,ORIG,DEP,DEST,ARR,SEQ_TIME
A21,9,BPK,0.582986111,X66,0.584375,2
A21,10,X66,0.584375,CNLEMOYN,0.586805556,3.5
A21,11,CNLEMOYN,0.586805556,SMT,0.590972222,6
A21,13,SMT,0.590972222,CNCANAL,0.591666667,1
A21,14,CNCANAL,0.591666667,MEWILSPR,0.594791667,4.5
A21,16,MEWILSPR,0.594791667,MELEMONT,0.6,7.5
A21,17,MELEMONT,0.6,,0.6,6.5
A21,20,MELOCKPO,0.605208333,XUD,0.60625,2.5
A21,21,XUD,0.60625,JOL,0.607638889,2