首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >迭代python中的CSV文件以查找具有前导空格的标题

迭代python中的CSV文件以查找具有前导空格的标题
EN

Stack Overflow用户
提问于 2018-07-12 03:48:55
回答 3查看 310关注 0票数 0

我正在处理一个包含歌曲及其ownershp属性的大型csv文件。每首歌曲记录都是从上到下写的,每个标题下面都有相关的作者和出版商的名字。因此,一首给定的歌曲可能由4-6行组成,这取决于有多少作者/出版商控制它(例如下面的标题行):

代码语言:javascript
复制
Title,RoleType,Name,Shares,Note
BOOGIE BREAK 2,ASCAP,Total Current ASCAP Share,100,
BOOGIE BREAK 2,W,MERCADO JOSEPH M,,
BOOGIE BREAK 2,P,CRAFTIN MUSIC,,
BOOGIE BREAK 2,P,NEXT DIMENSION MUSIC,,

我目前正在尝试遍历整个文件,以提取包含前导空格的所有歌曲标题(例如,“歌曲标题”)。下面是我目前使用的代码:

代码语言:javascript
复制
import csv
import re

with open('output/sws.txt', 'w') as sws:
    with open('data/ascap_catalog1.csv', 'r') as ac:
        ascap = csv.reader(ac, delimiter=',')
        ascap = list(ascap)
        for row in ascap:
            for strings in row:
                if re.search('\A\s+', strings):
                    row = str(row)
                    sws.write(row) 
                    sws.write('\n')
                else:
                    continue

由于我正在处理的这个文件csv文件的大小(~2 2GB),迭代并生成一个结果文件需要相当多的时间。然而,根据我得到的结果,看起来带有前导空格的歌曲标题都聚集在文件的开头。一旦这些歌曲都被列出,那么没有前导空格的普通歌曲就会出现。

有没有办法让这段代码在时间上更有效率?我尝试在每个for和if语句后使用一些breaks,但根据我使用的数量不同,它要么根本不影响语句,要么中断得太快,没有捕获任何行。

我还尝试将它包装在一个函数中并实现return,然而,由于某种原因,代码似乎只迭代第一行(不包括标题行,我会跳过它)。

非常感谢你抽出时间

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-07-12 03:58:33

list(ascap)不是在帮你的忙。reader对象是其内容的迭代器,但它们不会将所有内容加载到内存中,直到需要ti。只需直接迭代reader对象。

对于每一行,只需检查row[0][0].isspace()。这将检查第一个条目的第一个字符,这就是确定内容是否以空格开头所需的全部内容。

代码语言:javascript
复制
with open('output/sws.txt', 'w', newline="") as sws:
    with open('data/ascap_catalog1.csv', 'r', newline="") as ac:
        ascap = csv.reader(ac, delimiter=',')
        for row in ascap:
            if row and row[0] and row[0][0].isspace():
                print(row, file=sws)

你也可以尝试你的输出,比如保存所有你想在列表中保存的行,然后在末尾写入它们。听起来,如果所有的前导空格名称都在前面,那么您的输入可能会被排序。如果是这种情况,您可以只添加else: break来跳过文件的其余部分。

票数 0
EN

Stack Overflow用户

发布于 2018-07-12 03:58:27

您可以使用字典查找每首歌曲并对其所有关联值进行分组:

代码语言:javascript
复制
from collections import defaultdict
import csv, re
d = defaultdict(list)
count = 0 #count needed to remove the header, without loading the full data into memory
with open('filename.csv') as f:
  for a, *b in csv.reader(f):
    if count:
      if re.findall('^\s', a):
        d[a].append(b)
    count += 1
票数 0
EN

Stack Overflow用户

发布于 2018-07-12 04:15:17

这个对我来说工作得很好,而且看起来很简单。

代码语言:javascript
复制
import csv
import re

with open('C:\\results.csv', 'w') as sws:
    with open('C:\\ascap.csv', 'r') as ac:
        ascap = csv.reader(ac, delimiter=',')
        for row in ascap:
            if re.match('\s+', row[0]):
                sws.write(str(row)+ '\n')
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51293239

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档