Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/299.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
在用Python解析的csv文件中处理额外的换行符(回车符)?_Python_Csv_Newline - Fatal编程技术网

在用Python解析的csv文件中处理额外的换行符(回车符)?

在用Python解析的csv文件中处理额外的换行符(回车符)?,python,csv,newline,Python,Csv,Newline,我有一个CSV文件,其中的字段包含换行符,例如: A, B, C, D, E, F 123, 456, tree , very, bla, indigo (在这种情况下,第二行的第三个字段是“tree\n” 我尝试了以下方法: import csv catalog = csv.reader(open('test.csv', 'rU'), delimiter=",", dialect=csv.excel_tab) for row in catalog: print "Length: ",

我有一个CSV文件,其中的字段包含换行符,例如:

A, B, C, D, E, F
123, 456, tree
, very, bla, indigo
(在这种情况下,第二行的第三个字段是“tree\n”

我尝试了以下方法:

import csv
catalog = csv.reader(open('test.csv', 'rU'), delimiter=",", dialect=csv.excel_tab)
for row in catalog:
    print "Length: ", len(row), row
我得到的结果是:

Length:  6 ['A', ' B', ' C', ' D', ' E', ' F']
Length:  3 ['123', ' 456', ' tree']
Length:  4 ['   ', ' very', ' bla', ' indigo']
有人知道我如何快速删除无关的新行吗


谢谢!

如果您有非空白单元格,这将起作用

data = [['A', ' B', ' C', ' D', ' E', ' F'],
['123', ' 456', ' tree'],
['   ', ' very', ' bla', ' indigo']]

flat_list = chain.from_iterable(data)
flat_list = [cell for cell in flat_list if cell.strip() != ''] # remove blank cells

rows = [flat_list[i:i+6] for i in range(0, len(flat_list), 6)] # chunk into groups of 6 
print rows 
输出:

[['A', ' B', ' C', ' D', ' E', ' F'], ['123', ' 456', ' tree', ' very', ' bla', ' indigo']]
[['A', ' B', ' C', ' D', ' E', ' F'], ['123', ' 456', ' tree   ', ' very', ' bla', ' indigo']]
如果输入中有空白单元格,则大多数情况下都可以:

data = [['A', ' B', ' C', ' D', ' E', ' F'],
['123', ' 456', ' tree'],
['   ', ' very', ' bla', ' indigo']]

clean_rows = []
saved_row = []

for row in data:
    if len(saved_row):
        row_tail = saved_row.pop()
        row[0] = row_tail + row[0]  # reconstitute field broken by newline
        row = saved_row + row       # and reassemble the row (possibly only partially)
    if len(row) >= 6:
        clean_rows.append(row)
        saved_row = []
    else:
        saved_row = row


print clean_rows 
输出:

[['A', ' B', ' C', ' D', ' E', ' F'], ['123', ' 456', ' tree', ' very', ' bla', ' indigo']]
[['A', ' B', ' C', ' D', ' E', ' F'], ['123', ' 456', ' tree   ', ' very', ' bla', ' indigo']]
然而,即使是第二个解决方案也会因为这样的输入而失败

A,B,C,D,E,F\nG
1,2,3,4,5,6
在这种情况下,输入是不明确的,没有算法能够猜出您的意思是:

A,B,C,D,E,F
G\n1,2,3,4,5,6 
(或上述输入)


如果你是这样的话,你必须回到保存数据的人那里,让他们以更干净的格式保存数据(顺便说一句,在CSV文件中打开office引号换行要比Excel好得多)。

如果你知道列数,最好的方法是忽略行尾,然后拆分

像这样的

with open(filename, 'rU') as fp:
    data = ''.join(fp.readlines())

data = data.split(',')
for n in range(0, len(data), 6)
    print(data[n:n+6])
如果愿意,您可以轻松地将其转换为发电机:

def read_ugly_file(filename, delimiter=',', columns=6):
    with open(filename, 'rU') as fp:
        data = ''.join(fp.readlines())

    data = data.split(delimiter)
    for n in range(0, len(data), columns)
        yield data[n:n+columns]

for row in read_ugly_file('myfile.csv'):
    print(row)
这应该行得通。(警告:大脑编译代码)

以open('test.csv','rU')作为填充:
数据=[]
对于填充中的线:
temp_data=line.split(',')
尝试:
而len(temp_数据)<6:#列长度
temp_data.extend(infle.next())
除了停止迭代:通过
data.append(临时数据)

这与CSV模块一起工作,并清除空白字段和行:

import csv
import StringIO

data="""A, B, C, D, E, F
123, 456, tree

,,
, very, bla, indigo"""

f=StringIO.StringIO(data)   #used just to simulate a file. Use your file here...
reader = csv.reader(f)
out=[]
for line in reader:
    line=[x.strip() for x in line if x]   # remove 'if x' if you want blank fields
    if len(line):
        out.append(line)

print out        
印刷品:

[['A', ' B', ' C', ' D', ' E', ' F'], 
 ['123', '456', 'tree'], 
 ['very', 'bla', 'indigo']]
[['A', 'B', 'C', 'D', 'E', 'F'],
 ['123', '456', 'tree', 'very', 'bla', 'indigo']]
如果要将其分为6列块:

cols=6        
out=[i for sl in out for i in sl]                      # flatten out
out=[out[i:i+cols] for i in range(0, len(out), cols)]  # rechunk into 'cols' 
印刷品:

[['A', ' B', ' C', ' D', ' E', ' F'], 
 ['123', '456', 'tree'], 
 ['very', 'bla', 'indigo']]
[['A', 'B', 'C', 'D', 'E', 'F'],
 ['123', '456', 'tree', 'very', 'bla', 'indigo']]

如果每行中的字段数相同且字段不能为空:

from itertools import izip_longest

nfields = 6
with open(filename) as f:
     fields = (field.strip() for line in f for field in line.split(',') if field)
     for row in izip_longest(*[iter(fields)]*nfields): # grouper recipe*
         print(row)


假设您有以下Excel电子表格:

注:

  • C2中的多系细胞
  • C1和D3中嵌入逗号
  • 空白单元格和D4中有空格的单元格
  • 将其保存为Excel中的CSV,您将获得以下CSV文件:

    A1,B1,"C1,+comma",D1
    ,B2,"line 1
    line 2",D2
    ,,C3,"D3,+comma"
    ,,,D4 space
    
    A, B, C, D, E, F
    123, 456, tree
    , very, bla, indigo
    

    假定,您希望将其读入Python中,其中空白单元格仍然有意义,并且嵌入逗号正确处理。 那么这个,

    with open("test.csv", 'rU') as csvIN:
        outCSV=(line for line in csv.reader(csvIN, dialect='excel'))
    
        for row in outCSV:
            print("Length: ", len(row), row) 
    
    正确生成Excel中表示的4x4列表矩阵:

    Length:  4 ['A1', 'B1', 'C1,+comma', 'D1']
    Length:  4 ['', 'B2', 'line 1\nline 2', 'D2']
    Length:  4 ['', '', 'C3', 'D3,+comma']
    Length:  4 ['', '', '', 'D4 space']
    
    您发布的示例CSV文件在字段周围缺少引号,并带有“额外换行符”,使得该换行符的含义不明确。它是新行还是多行字段

    因此,您只能解释此csv文件:

    A1,B1,"C1,+comma",D1
    ,B2,"line 1
    line 2",D2
    ,,C3,"D3,+comma"
    ,,,D4 space
    
    A, B, C, D, E, F
    123, 456, tree
    , very, bla, indigo
    
    作为一维列表,如下所示:

    with open("test.csv", 'rU') as csvIN:
       outCSV=[field.strip() for row in csv.reader(csvIN, delimiter=',') 
                  for field in row if field]
    
    这将生成此一维列表:

    ['A', 'B', 'C', 'D', 'E', 'F', '123', '456', 'tree', 'very', 'bla', 'indigo']
    
    然后,您可以根据需要将其解释并重新分组到任何子分组中

    python中惯用的重新分组方法如下所示:

    或者,如果您想要列表列表,这也是惯用的:

    >>> [outCSV[i:i+6] for i in range(0, len(outCSV),6)]
    [['A', 'B', 'C', 'D', 'E', 'F'], ['123', '456', 'tree', 'very', 'bla', 'indigo']]
    

    如果您可以更改CSV文件的创建方式,解释起来就不那么模棱两可了。

    逗号是否始终位于字段的结尾或内部,即不在开头?或者,列数是否固定?如果两者都不固定,则无法执行。在本例中,列数固定为6。是否保证每个字段只有一行换行符?您还希望必须在字段内处理逗号吗?即带引号的字段?是否
    '、
    '\n'
    都终止字段,并且不能有空字段?您要查找的结果是什么?如果有,应该是
    [['a'、'B'、'C'、'D'、'e'、'F']、['123'、'456'、'tree'、'very'、'bla'、'indigo']
    或其他什么?是否有任何字段嵌入了引号,如:
    A,“B,C”,D
    ?额外的换行符在
    树之后
    感谢您的建议。但是,(可能我没有正确表达我的要求)我的数据可能如下所示:data=[['A',''C',''E','F'],['123','tree'],在这种情况下,删除空元素并没有真正的帮助。啊-我明白了…好了…越来越近了…再来一次:)@carrot top不明白为什么它不能与嵌入的逗号一起工作-只要csv读取器处理它们,我的算法中就没有任何东西会因为嵌入的逗号而中断。看起来你将所有行都保留在内存中,这对大文件不起作用。如果不立即将整个文件加载到内存中,我怎么能做到同样的事情呢?请r@Maria Zverina的版本对我来说,它更好,更具Python风格,可能更健壮。@Chinmay Kanchi:怎么会这样?它处理空行、空白字段,CSV处理CSV内容的复杂性,并且很容易重新检查N列字段。+1,但这对使用生成器而不是列表的内存来说更友好。谢谢你的回答。仅供参考,您正在从迭代器创建一个迭代器,这是无用的。
    outCSV=(csv.reader(csvIN,dialent='excel')中的行对行)
    可以替换为
    outCSV=csv.reader(csvIN,dialent='excel')