我有一个 CSV 文件,它按以下顺序自动更新一些数据
A,B,C,D,E,F
4,2,6,4,8,9
D,C,A,B,E,F
6,4,5,8,6,2
E,F,A,C,D
4,2,7,6,5
正如您所注意到的,标题值在不同的行中以不同的顺序出现。有时还会缺少一个标题列值。
要求是用一致的标题和低于它的所有值对其进行排序。例如
A,B,C,D,E,F
4,2,6,4,8,9
A,B,C,D,E,F
5,8,4,6,6,2
A,B,C,D,E,F
7, ,6,5,4,2
或
A,B,C,D,E,F
4,2,6,4,8,9
5,8,4,6,6,2
7, ,6,5,4,2
我尝试使用以下代码对其进行排序,但它只对第一行进行排序,然后按原样打印。
with open('mycsv.csv', 'r') as infile, open('reordered.csv', 'a') as outfile:
fieldnames = ['A','B','C','D','E','F','G']
writer = csv.DictWriter(outfile, fieldnames=fieldnames)
writer.writeheader()
for row in csv.DictReader(infile):
writer.writerow(row)
有关如何实现此目的的任何指示都会有所帮助。谢谢。
最佳答案
您可以导入您的文件,并继续读取 2 行(标题 + 数据)并为它们创建一个字典。您将字典添加到包含所有数据的列表中。 你得到最大的字典(包含最多键的字典),对其进行排序并写回所有数据。
在缺少键的字典中,您可以用空字符串替换它的值:
创建数据文件:
with open("t.csv","w") as f:
f.write("""A,B,C,D,E,F
4,2,6,4,8,9
D,C,A,B,E,F
6,4,5,8,6,2
E,F,A,C,D
4,2,7,6,5""")
然后:
# read in data as list of dicts, each dict contains 2 rows worth of data
data = []
with open("t.csv") as f:
while True:
try:
# get a header line and a data line
header = next(f).strip().split(",")
d = next(f).strip().split(",")
# create a dict from it and append it to your data collection
data.append( {k:v for k,v in zip(header,d)} )
except StopIteration:
print("done")
break
# get a sorted set of all keys in all dicts:
keys = set()
for k in data:
keys.update(k)
keys = sorted(keys)
# write the data again
with open("new_t.csv","w") as f:
# write headers once
f.write(",".join(keys))
f.write("\n")
for d in data:
f.write(",".join( ( d.get(k,"") for k in keys )))
f.write("\n")
# check:
with open("new_t.csv","r") as f:
print(f.read())
结果文件:
A,B,C,D,E,F
4,2,6,4,8,9
5,8,4,6,6,2
7,,6,5,4,2
我使用 python3 样式打印 - 但代码在 python 2.7 和 3.x 中工作相同。
确保检查您的源文件是否包含标题+数据行且没有空行,否则您必须调整代码以省略空行。
关于Python-按常量列标题排列 CSV 文件的不同行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52791262/