【问题标题】:Regular Expression, Matrix, CSV in PythonPython 中的正则表达式、矩阵、CSV
【发布时间】:2012-08-10 18:15:38
【问题描述】:

我看过一些关于 numpy 模块等的相关帖子。我需要使用 csv 模块,它应该可以解决这个问题。虽然这里已经写了很多关于使用 csv 模块的文章,但我并没有完全找到我正在寻找的答案。提前非常感谢

基本上我有以下函数/伪代码(选项卡没有很好地复制...):

import csv

def copy(inname, outname):
   infile = open(inname, "r")
   outfile = open(outname, "w")
   copying = False ##not copying yet

# if the first string up to the first whitespace in the "name" column of a row
# equals the first string up to the first whitespace in the "name" column of 
# the row directly below it AND the value in the "ID" column of the first row
# does NOT equal the value in the "ID" column of the second row, copy these two 
# rows in full to a new table.

例如,如果 inname 如下所示:

ID,NAME,YEAR, SPORTS_ALMANAC,NOTES

(前一千行)

1001,New York Mets,1900,ESPN

1002,New York Yankees,1920,Guiness

1003,Boston Red Sox,1918,ESPN

1004,Washington Nationals,2010 

(直到最后一行的最后大量行)

1231231231235,Detroit Tigers,1990,ESPN

然后我希望我的输出看起来像:

ID,NAME,YEAR,SPORTS_ALMANAC,NOTES

1001,New York Mets,1900,ESPN

1002,New York Yankees,1920,Guiness

因为字符串“New”是相同的字符串,直到“Name”列中的第一个空格,并且 ID 不同。需要明确的是,我需要代码尽可能通用,因为“New”上的正则表达式不是我需要的,因为常见的第一个字符串实际上可以是任何字符串。在第一个空格之后发生什么并不重要(即“华盛顿国民队”和“华盛顿特区”应该仍然给我一个打击,就像上面纽约的例子一样......)

我很困惑,因为在 R 中有一种方法: inname$name 通过特定行中的值轻松搜索。我尝试先用 R 编写我的脚本,但它变得令人困惑。所以我想坚持使用 Python。

【问题讨论】:

  • 抱歉,刚刚修好了!
  • 如果您已经解决了自己的问题,并且您认为该解决方案对社区很有价值,那么如果您编写并接受自己的答案,那就太好了。
  • @zigg:我认为他指的是格式问题。最初输入数据中没有给出逗号,因此解析起来似乎很麻烦。
  • 抱歉给您带来了困惑,我只是修复了格式问题,而不是问题。
  • 我很困惑。你是说有重复的行(你没有显示任何重复)并且你想删除重复的行吗?或者有许多 New York Yankees 行具有不同的 IDs,而您希望它们都具有相同的 ID

标签: python regex csv


【解决方案1】:

这是你想要的吗(Python 3)?

import csv 

def first_word(value):
    return value.split(" ", 1)[0]

with open(inname, "r") as infile:
    with open(outname, "w", newline="") as outfile:
        in_csv = csv.reader(infile)
        out_csv = csv.writer(outfile)

        column_names = next(in_csv)
        out_csv.writerow(column_names)

        id_index = column_names.index("ID")
        name_index = column_names.index("NAME")

        try:
            row_1 = next(in_csv)
            written_row = False

            for row_2 in in_csv:
                if first_word(row_1[name_index]) == first_word(row_2[name_index]) and row_1[id_index] != row_2[id_index]:
                    if not written_row:
                        out_csv.writerow(row_1)

                    out_csv.writerow(row_2)
                    written_row = True
                else:
                    written_row = False

                row_1 = row_2
        except StopIteration:
            # No data rows!
            pass

对于 Python 2,使用:

with open(outname, "w") as outfile:
    in_csv = csv.reader(infile)
    out_csv = csv.writer(outfile, lineterminator="\n")

【讨论】:

  • 是的!奇迹般有效! (除了我不得不取出 newline="" 因为那给了我一个错误)。非常感谢!!!另外,除了 StopIteration: pass 是如何工作的?
  • 我已经编辑了我的答案。如果没有行,则next(in_csv) 将引发StopIteration。我只在没有数据行的情况下才捕获它,而不是在没有标题行的情况下(即根本没有行)。
  • 非常感谢您的帮助和有益的解释。如果您不介意,还有一个快速的问题:我将如何调整代码,而不是将我们想要的行写入新文件,而是在输入文件中添加一个额外的列并用“1”标记这些行而是在新列中?
  • 您可以在写出之前通过向行(即 Python 列表)添加新条目来添加新列。您不能就地修改输入文件;您必须创建一个新文件,然后用新文件替换旧文件。
猜你喜欢
  • 1970-01-01
  • 2022-11-03
  • 2013-02-28
  • 1970-01-01
  • 2014-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多