【问题标题】:Write more than 65535 rows to a csv file in Python? [closed]在 Python 中将超过 65535 行写入 csv 文件? [关闭]
【发布时间】:2021-02-15 08:28:13
【问题描述】:

我在 Python 脚本中有以下逻辑:

def importAndAnalyze(rowLimit = 3):
    layerProperties = iface.addVectorLayer("Downloads/parcels-shp/parcels.shp", "Parcels", "ogr")
    if not layerProperties:
        print("layerProperties failed to load!")
    layerEntrances = iface.addVectorLayer("Downloads/Metro_Stations-shp/Metro_Stations.shp", "Metro_Stations", "ogr")
    if not layerEntrances:
        print("layerEntrances failed to load!")
    features = layerProperties.getFeatures()
    counter = 0
    featuresSelected = []
    Path('Desktop/output.csv').touch()

    with open('Desktop/output.csv', 'w') as csvfile:
        csvWriter = csv.writer(csvfile, delimiter=',', quotechar='"', quoting=csv.QUOTE_NONNUMERIC)
        csvWriter.writerow(['Tooltip', 'Lat','Lon', 'Distance'])
        for feature in features:
            if counter < rowLimit:
                csvWriter.writerow([feature['TOOLTIP'], feature.geometry().centroid().asPoint().y(),feature.geometry().centroid().asPoint().x(), Ranker.calculateDistance(feature, layerEntrances)])
                if counter % 100 == 0:
                    csvfile.flush()
            else:
                break
            counter += 1

Ranker.importAndAnalyze(1000000)

当我输入 800,000 行信息并将 rowLimit 变量设置为 100 万行时,它当前恰好将 65,535 行保存到 output.csv 文件中,然后停止保存新行,即使脚本继续运行数小时也是如此。

如何让我的脚本保存其他 734,465 行?

===

编辑:在 cmets/answers 中有很多关于我的 rowLimit 变量是否实际设置为一百万的正确猜测。所以我添加了更多代码来显示它是如何运行的上下文。

【问题讨论】:

  • 如果rowlimit 的目的是限制文件的大小,那么您的代码应该在到达for 循环时将break 排除在外,而不是无休止地循环通过features并且对它检索到的内容不做任何事情。
  • 您的 csv 文件打开上下文中的 w 选项可能是问题所在。将其更改为 a 以附加数据。
  • @BoarGules 谢谢,这是关于打破循环的好建议。我已经编辑了代码示例以遵守该建议。
  • Python 不会阻止您编写任意数量的行。你确定你有超过 65536 行吗?你确定rowLimit1000000 吗?你确定你的counter 开始一个0 吗?你确定这部分代码是罪魁祸首吗?你能证明吗?
  • Python 中没有限制拒绝 65535 行之后的内容。请edit您的问题提供minimal reproducible example

标签: python csv file


【解决方案1】:

csv 模块本身没有施加这样的约束。当您的代码到达变量 rowLimit (您的问题中未定义)时,您的代码将停止写入,因此显而易见且简单的解决方案是将其取出。

这是一次重构的尝试,它还会重命名变量以符合 Python 约定。

with open('Desktop/output.csv', 'w') as csvfile:
    csv_writer = csv.writer(csvfile, delimiter=',', quotechar='"', quoting=csv.QUOTE_NONNUMERIC)
    csv_writer.writerow(['Tooltip', 'Lat','Lon', 'Distance'])
    for counter, feature in enumerate(features):
        # if counter == row_limit:
        #     raise StopIteration('row_limit reached')
        csv_writer.writerow([feature['TOOLTIP'], feature.geometry().centroid().asPoint().y(),feature.geometry().centroid().asPoint().x(), Ranker.calculateDistance(feature, layerEntrances)])
        if counter % 100 == 0:
            csvfile.flush()

您当然有可能使用程序读取无法处理任意大文件的生成的 CSV 文件;至少 Excel 似乎对大于 65,535 行的工作表有问题(但朋友不要让朋友使用 Excel)。

【讨论】:

  • 感谢您的回答。谷歌搜索似乎表明这个行数是相关的。 google.com/search?q=65535+rows+csv&oq=65535+rows+csv
  • 使用本地 Python 进行一个简单的练习应该会发现它可以轻松编写一百万行而没有问题。您的 Google 搜索似乎主要返回 Java 的结果。可能 Excel 也有大文件的问题,但谁想使用 Excel?
  • 啊哈!我正在使用 Apple Numbers 打开此文件。我认为 Excel 在十年前解决了工作表大小问题,但也许 Apple Numbers 仍然没有。我来看看 Vim 中的文件...
  • 那你在哪个操作系统上?我无法在 macOS 或 Linux 上进行复制。
  • MacOS。我查看了 Vim,果然,出现了更多行。所以这是一个苹果号码的问题。如果您编辑此答案以包含该信息,我会将其标记为正确答案。
【解决方案2】:
with open('Desktop/output.csv', 'w') as csvfile:
    csvWriter = csv.writer(csvfile, delimiter=',', quotechar='"', quoting=csv.QUOTE_NONNUMERIC)
    csvWriter.writerow(['Tooltip', 'Lat','Lon', 'Distance'])
    counter = 0
    for feature in features[:rowLimit]:
        csvWriter.writerow([feature['TOOLTIP'], feature.geometry().centroid().asPoint().y(),feature.geometry().centroid().asPoint().x(), Ranker.calculateDistance(feature, layerEntrances)])
        if counter % 100 == 0:
            csvfile.flush()
        counter += 1
    csvfile.flush()

【讨论】:

  • 感谢您的回答。为密集道歉:你改变了什么?
  • 你需要在循环结束时有一个flush()来处理最后一批。
  • 实际上不需要最后一次刷新,因为关闭文件(退出上下文管理器块时会发生)无论如何都会刷新它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-01-25
  • 2016-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-22
  • 2016-09-05
相关资源
最近更新 更多