Python 尝试删除基于列值的csv文件中的行
我试图根据列是否具有唯一值来删除csv文件中的重复行。我的代码如下所示:Python 尝试删除基于列值的csv文件中的行,python,csv,duplicates,Python,Csv,Duplicates,我试图根据列是否具有唯一值来删除csv文件中的重复行。我的代码如下所示: seen = set() for line in fileinput.FileInput('DBA.csv', inplace=1): if line[2] in seen: continue # skip duplicated line seen.add(line[2]) print(line, end='') {'b', '"', 't', '/', 'k'} 我试图获取每行
seen = set()
for line in fileinput.FileInput('DBA.csv', inplace=1):
if line[2] in seen:
continue # skip duplicated line
seen.add(line[2])
print(line, end='')
{'b', '"', 't', '/', 'k'}
我试图获取每行中2个索引列的值,并检查它是否唯一。但出于某种原因,我的电视机看起来是这样的:
seen = set()
for line in fileinput.FileInput('DBA.csv', inplace=1):
if line[2] in seen:
continue # skip duplicated line
seen.add(line[2])
print(line, end='')
{'b', '"', 't', '/', 'k'}
关于我的逻辑哪里有缺陷,有什么建议吗?您正在逐行读取文件,因此当您选择
行[2]
时,实际上是在选择运行此操作的每行的第三个字符
如果要为每行捕获第二列的值,需要首先解析CSV,例如:
import csv
seen = set()
with open("DBA.csv", "rUb") as f:
reader = csv.reader(f)
for line in reader:
if line[2] in seen:
continue
seen.add(line[2])
print(line) # this will NOT print valid CSV, it will print Python list
如果你想在适当的地方编辑你的CSV,恐怕会有点复杂。如果您的CSV不是很大,您可以将其加载到内存中,截断它,然后写下您的行:
import csv
seen = set()
with open("DBA.csv", "rUb+") as f:
handler = csv.reader(f)
data = list(handler)
f.seek(0)
f.truncate()
handler = csv.writer(f)
for line in data:
if line[2] in seen:
continue
seen.add(line[2])
handler.writerow(line)
否则,您必须逐行读取文件,并使用将传递到csv.reader()
的缓冲区对其进行解析,检查其第三列的值,如果未看到,则将该行写入实时编辑文件。如果看到,你必须在写下一行之前回到上一行开始,等等
当然,如果你很了解行结构,那么你不需要使用
csv
模块,因为行结构可以简化事情(你不需要处理左右传递缓冲区的问题),但是对于通用解决方案,最好让csv
模块来完成你的任务。你正在逐行阅读文件,因此,当您选择行[2]
时,实际上是在选择运行此操作的每行的第三个字符
如果要为每行捕获第二列的值,需要首先解析CSV,例如:
import csv
seen = set()
with open("DBA.csv", "rUb") as f:
reader = csv.reader(f)
for line in reader:
if line[2] in seen:
continue
seen.add(line[2])
print(line) # this will NOT print valid CSV, it will print Python list
如果你想在适当的地方编辑你的CSV,恐怕会有点复杂。如果您的CSV不是很大,您可以将其加载到内存中,截断它,然后写下您的行:
import csv
seen = set()
with open("DBA.csv", "rUb+") as f:
handler = csv.reader(f)
data = list(handler)
f.seek(0)
f.truncate()
handler = csv.writer(f)
for line in data:
if line[2] in seen:
continue
seen.add(line[2])
handler.writerow(line)
否则,您必须逐行读取文件,并使用将传递到csv.reader()
的缓冲区对其进行解析,检查其第三列的值,如果未看到,则将该行写入实时编辑文件。如果看到,你必须在写下一行之前回到上一行开始,等等
当然,如果您非常了解行结构,可以简化事情(您不需要处理左右传递缓冲区的问题),那么您不需要使用
csv
模块,但是对于通用解决方案,最好让csv
模块来完成您的任务。行可以通过字符进行匹配,不是按字段。要处理字段,您需要使用csv.reader
,而不是fileinput
。据我所知,fileinput允许我在位编辑文件。csv.reader也可以这样做吗?@Rainoa非常确定fileinput
只是创建了一个内存备份来“就地修改”。您可以手动执行此操作。它的主要用例是处理多个文件,但对于单个文件,这非常简单。不,fileinput
用于迭代目录中的多个类似文件,尽管可以接受单个文件。默认情况下,该方法将行读取为文本,因此行[2]
调用将为您提供行字符串中的第二个字符。您必须调用line.split(“,”[2]
来获取第三个值,仍然是字符串。不要使用line.split(“,”
)。这种方法是错误的,你必须考虑csv引用。行是可由字符,而不是由字段。要处理字段,您需要使用csv.reader
,而不是fileinput
。据我所知,fileinput允许我在位编辑文件。csv.reader也可以这样做吗?@Rainoa非常确定fileinput
只是创建了一个内存备份来“就地修改”。您可以手动执行此操作。它的主要用例是处理多个文件,但对于单个文件,这非常简单。不,fileinput
用于迭代目录中的多个类似文件,尽管可以接受单个文件。默认情况下,该方法将行读取为文本,因此行[2]
调用将为您提供行字符串中的第二个字符。您必须调用line.split(“,”[2]
来获取第三个值,仍然是字符串。不要使用line.split(“,”
)。这种方法被打破了,你必须考虑csv报价。