确定需要更新主要示例。
我有这个: Joining all rows of a CSV file that have the same 1st column value in Python (首先我必须道歉,因为没有得到如何再次提高...)
我有一个x.CSV文件,如下所示: INT; INT2; STRING; STRING; STRING; STRING; STRING; STRING; STRING; STRING; STRING; and_so_on ......
0; 0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;; - 1.0; 0; 0; 1; -1.0
0; 0 ;;;;;;;;;;;;; 30.0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;
0; 0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 160.0 ;;; ;;;;;;;;;;;;;;;;;;;
0; 0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 0.0; ;;;;;;;;;;;;;;;;;;;
0; 0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 0.0 ;;;;;;;;;;;;;;;;;;;
0; 0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1668.0 ;;;;;; ;;;;;;;;;;;;;;;;;;;
0; 0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1672.0 ;;;;; ;;;;;;;;;;;;;;;;;;;
0; 0 ;;;;;;;;;;;;;;;;;; 0.0 ;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;
0; 0 ;;;;;;;;;;;;;;;;;;; 74.0 ;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;
1; 1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;; 0.0 ;;;;;;;;;;;;
1; 1; 0.0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;
3; 3; 4.0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;
3; 3 ;;;;;;;;;;;;;;;;;;;;;;;;; 75.0 ;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;
5; 5; 0.0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;
5; 5 ;;;;;;;;;;;;;;;;;;;;;;;;; 85.0 ;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;
现在,我需要一种方法将具有相同第一列名称的所有行连接到一列中,例如:
INT; INT2; STRING; STRING; STRING; STRING; STRING; STRING; STRING; STRING; STRING; and_so_on ......
0; 0 ;;;;;;;;;;;;; 30.0 ;;;;; 0.0; 74.0 ;;;;;;;;;;;;;;;; 1668.0; 1672.0 ;;; 160.0 ;;;;; 0.0; 0.0 ;;;;;;;;;;;;;; - 1.0; 0; 0; 1; -1.0
1; 1; 0.0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;; 0.0 ;;;;;;;;;;;;
3; 3; 4.0 ;;;;;;;;;;;;;;;;;;;;;;;; 75.0 ;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;
5; 5; 0.0 ;;;;;;;;;;;;;;;;;;;;;;;; 85.0 ;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;
它是相同数量的colums(即使“resultrow”0; 0 ....可能有太多“;”因为我伪造它;-) 数字只在同一个indexrow中出现一次,所以它有点“合并同一个indexrow” 我需要读取> 20k(也可以是> 1百万行)长文件的东西。 压缩列表 并将文件再次写回磁盘。
帮助者只是向代码的方向倾斜,我无法: - /(但是...... :-) 最尊重 - 我不编码脸红 - 我可以阅读但不设计它。 我发布代码将是 - 让我们说有趣: - )
我非常赞赏这些帮助。 br //
答案 0 :(得分:0)
import csv
from itertools import izip_longest
def merge_rows(a, b):
return [x or y for x,y in izip_longest(a, b, fillvalue='')]
def main():
data = {}
with open("infile.csv", "rb") as inf:
incsv = csv.reader(inf, delimiter=";")
header = next(incsv, [])
for row in incsv:
label = row[0]
try:
data[label] = merge_rows(data[label], row)
except KeyError:
data[label] = row
# write data in sorted order by label
keys = sorted(data, key=lambda k: int(k)) # Python 2
# keys = sorted(data.keys(), key=lambda k: int(k)) # Python 3
with open("outfile.csv", "wb") as outf:
outcsv = csv.writer(outf, delimiter=";")
outcsv.writerow(header)
outcsv.writerows(data[key] for key in keys)
if __name__=="__main__":
main()
编辑:我根据您的示例数据制作了一些mod:
为csv读者和作者添加了delimiter=";"
参数
添加了读取和写入标题的代码
添加了一个关键子句,因此排序顺序是数字,而不是词典
工作原理:
for row in incsv
:对于数据文件中的每一行,我们都会得到一个列表 - 类似于["0", "0", "", "", "", "", "", "", "", "", "", "", "-1.0", "0", "0", "-1", "0"]
。然后label = row[0]
为标签提供值"0"
- 您想要的第一列值 - 我们会查找data[label]
,这是来自具有该标签的所有预先存在的行的合并行。
如果该组合行已经存在,我们会将新行合并到其中(stored_row = merge_rows(stored_row, new_row)
;否则会使用新行值(["0", "0", "", "", "", "", "", ""
等)创建。所以有效merge_rows
除了第一次出现之外,每个标签的每次出现都会被调用。
merge_rows
获取一对列表并将它们合并 - izip_longest
返回相应的条目,即izip_longest([0, 1, 2], ["a", "b", "c"])
给出(0, "a"), (1, "b"), (2, "c")
。如果一个列表比另一个列表短,则用fillvalue
填充它以匹配它收到的最长列表的长度。 x
和y
会为每个列表分配相应的值,我们or
将它们放在一起,因为......好吧,因为or
按照您想要的方式组合它们({{ 1}},'' or '1' == '1'
,'1' or '' == '1'
)。然后它获取所有结果值并将它们作为列表返回 - 结果组合行。
希望有所帮助。