0

我想创建一个 Python 脚本,该脚本将打开 csv(或 xls)文件,并使用输入框将 Excel 公式复制并粘贴到特定行...然后将其应用于该行中的其余空行柱子。为了帮助形象化,这里有一个例子

DATA, FORMULA
001,  [here would be inserted the formula]
002,  [here would be populated the amended formula]
003,  [here would be populated the amended formula]
004,  [here would be populated the amended formula]

所以,这个想法是有一个脚本,它会让我输入框询问 - 你想从哪一行开始?| answer = B2 - 你想在那里填充什么公式?| "=COUNTIF(A:A,A2)"

...然后它将填充 B2 列中的公式并自动填充下一个 B3、B4、B5 和 B6,其中公式调整为特定单元格。我想这样做的原因是我处理大型 excel 文件,这些文件经常在我的计算机上崩溃,所以我想在不运行 Excel 本身的情况下执行它。

我做了一些研究,但 xlwt 可能无法做到这一点。您能帮我找到解决方案吗?我该怎么做?我将不胜感激您的任何想法和指导。

4

1 回答 1

0

不幸的是,如果不在代码中实现电子表格程序 (Excel) 的一部分,就无法完成您想做的事情。那里没有捷径。

至于文件格式,Python 可以本地处理 CSV 文件,但我认为您在将原始公式(与数字或文本内容相反)从 CSV 导入 Excel 本身时会遇到麻烦。

由于您已经使用 Python,因此将您的逻辑从电子表格移到程序中可能是一个更好的主意:使用 Excel 或其他电子表格程序输入您的数据,只输入数字,并使用您的脚本而不是修改工作表,但要影响您需要的计算 - 可能将数据存储在 SQL 数据库中(在这种情况下,Python 的内置 SQLite 对于单用户应用程序会很好地执行) - 并将计算出的数字输出到电子表格文件,或者可能,使用 matplotlib 直接从 Python 生成您的意图图表。

也就是说,您所要求的可以通过 Python 完成 - 但随着数据集的增长,它可能会导致您的一般工作流程变得越来越复杂 -

Hre - 这些辅助函数将允许您从 Excel 单元格命名约定转换为数字,反之亦然 - 这样您就可以拥有在 Python 编程中操作的数字索引。

然而,解析输入的公式以提取单元格地址并非易事

  • 将它们重新放入公式中,在调整数字索引后应该容易得多)。我建议您在脚本中对公式进行硬编码,而不是允许输入任何可能的公式。

    def parse_num(address): x = "" for chr in (address): if chr.isdigit(): x += chr return int(x) - 1

    def parse_col(address): x = 0 for chr in address: if chr.isdigit(): break x = x * 26 + (ord(chr.upper()) - ord("A")) return x

    def render_address(col, row): base = 26 power = col // base col_letters = "" tmp_col = col for p in xrange(power, -1, -1): dig = tmp_col // (base ** p) letter = chr(dig + ord("A")) col_letters += letter tmp_col %= base ** p return col_letters + str(row + 1)

现在,如果您愿意在 Python 中工作,只需将数据输入为 CSV 并使用一个小型 Python 程序来获取结果,而不是尝试将它们放入电子表格中 - 对于上面的公式COUNTIF(A:A,A2)基本上,您想要计算有多少其他行将第一列作为这一行 - 对于 750000 个数据位置,这在 Python 中是小菜一碟 - (如果所有数据都不适合 RAM,它会开始变得更难 - 但大约 100 会发生这种情况2GB 机器中的数百万个数据点 - 那时你仍然可以使用专门的结构将所有内容放入 RAM 中 - 上面它将开始需要更多的逻辑,正如我上面提到的那样,使用 SQLIte 将有几行长。

现在,给定包含一列数据的 CSV 文件的代码会生成第二个 CSV 文件,其中第二列包含第一列中数字的出现总数:

import csv
from collections import Counter

data_count = Counter()
with open("data.csv", "rt") as input_file:
    reader = csv.reader(input_file)
    # skip header:
    reader.next()
    for row in reader():
        data_count[int(row[0])] += 1

# everything is accounted for now - output the result:
with open("data.csv", "rt") as input_file, open("counted_data.csv", "wt") as output_file:
    reader = csv.reader(input_file)
    writer = csv.writer(output_file)
    header = reader.next()
    header.append("Count")
    writer.writerow(header)
    for row in reader():
        writer.writerow(row + [str(data_count[int(row[0])])] )

仅当您确实需要在最终文件中按顺序排列所有第一列时。如果您想要的只是第 1 列中每个数字的计数,无论它们出现的顺序如何,您只需要在data_count第一个块之后的数据 - 您可以在 Python 提示符中交互式地使用它,并得到小数的结果其次,在电子表格程序中需要数十分钟。

如果您有不适合内存的数据集,您只需使用比这更简单的脚本将它们放入数据库中,您仍然可以在几分之一秒内获得结果。

于 2013-06-27T13:46:16.323 回答