【问题标题】:How to write clean data to a file in python in tabulated format如何以表格格式将干净的数据写入python中的文件
【发布时间】:2015-08-04 14:25:24
【问题描述】:

问题:从 Twitter 文本中删除超链接、数字和符号,如 ^&*$ etc。推文文件为 CSV 表格格式,如下所示:

s.No.   username   tweetText

1.      @abc  This is a test #abc example.com
2.      @bcd  This is another test #bcd example.com 

作为python的新手,我搜索并串在一起以下代码,感谢here给出的代码:

import re
fileName="path-to-file//tweetfile.csv"
fileout=open("Output.txt","w")
with open(fileName,'r') as myfile:
    data=myfile.read().lower() # read the file and convert all text to lowercase
    clean_data=' '.join(re.sub("(@[A-Za-z0-9]+)|([^0-9A-Za-z \t])|(\w+:\/\/\S+)"," ",data).split()) # regular expression to strip the html out of the text
fileout.write(clean_data+'\n') # write the cleaned data to a file
fileout.close()
myfile.close()
print "All done"

它会进行数据剥离,但输出文件格式不是我想要的。输出文本文件在一行中,如

s.no username tweetText 1 abc这是一条清理过的推文2 bcd这是另一条清理过的推文3 efg这是另一条清理过的推文

如何修复此代码以提供如下所示的输出:

s.No. username  tweetText

1  abc  This is a test

2  bcd  This is another test

3  efg  This is yet another test 

我认为需要在正则表达式代码中添加一些内容,但我不知道它可能是什么。任何指示或建议都会有所帮助。

【问题讨论】:

  • 你想怎么从some textThis is a test
  • 感谢 Carsten Hagemann 指出该异常。我现在已经更正了这个例子。
  • 尝试为 clean_data 中的每个元素写入元素 + '\n' 或逐行读取文件并通过从行中提取 clean_data 以相同方式处理它,如果它不为空,则写入 clean_data + '\n' .

标签: python regex twitter


【解决方案1】:

您可以在一个循环中读取、清理和写出该行。您还可以使用 CSV 模块来帮助您构建结果文件。

import csv
import re

exp = r"(@[A-Za-z0-9]+)|([^0-9A-Za-z \t])|(\w+:\/\/\S+)"

def cleaner(row):
   return [re.sub(exp, " ", item.lower()) for item in row]

with open('input.csv', 'r') as i, open('output.csv', 'wb') as o:
    reader = csv.reader(i, delimiter=',')  # Comma is the default
    writer = csv.writer(o, delimiter=',')

    # Take the first row from the input file (the header)
    # and write it to the output file

    writer.writerow(next(reader))

    for row in reader:
        writer.writerow(cleaner(row)) 

csv 模块正确地知道如何在项目之间添加分隔符;只要你传递一个项目的集合。

那么,cleaner 方法从输入文件中获取行中的每个项目(列),将替换应用于项目的小写版本;然后返回一个列表。

其余代码只是打开文件,使用输入和输出文件所需的分隔符配置 CSV 模块(在示例代码中,两个文件的分隔符都是制表符,但您可以更改输出分隔符)。

接下来,读取输入文件的第一行并将其写入输出文件。该行没有进行任何转换(这就是它不在循环中的原因)。

从输入文件中读取行会自动将文件指针放在下一行 - 所以我们只需遍历输入行(在阅读器中),为每一行应用清理函数 - 这将返回一个列表 - 然后使用writer.writerow()将该列表写回输出文件。

【讨论】:

  • writer = csv.writer(o, delimiter='\t') 替换为writer = csv.writer(o, delimiter=',') - 这是作者将使用的分隔符。
  • 您的代码有问题。当我执行它时,写入一个 csv 文件,但列没有分开。所以基本上它只是将 s.No username,tweetText 写入单个列。输出应该是多列,如 1、abc、测试消息。即使我将 writer = csv.writer(o, delimiter='\t') 替换为 writer = csv.writer(o, delimiter=',')
  • 您确定您正在读取的文件在列之间有制表符而不是空格?
  • 非常感谢您的及时答复。我正在阅读的文件也是 CSV 格式,所以我只是替换了您的代码,例如 reader = csv.reader(i, delimiter=',') 和 writer = csv.writer(o, delimiter=',') 现在给了我想要的输出。请编辑您的原始代码,以便我也可以将其标记为 +1。再次感谢您。
【解决方案2】:

不要一次将 re.sub() 和 .lower() 表达式应用于整个文件,而是尝试像这样遍历 CSV 文件中的每一行:

for line in myfile:
    line = line.lower()
    line = re.sub("(@[A-Za-z0-9]+)|([^0-9A-Za-z \t])|(\w+:\/\/\S+)"," ",line)
    fileout.write(line+'\n')

当您使用with <file> as myfile 表达式时,也无需在程序结束时关闭它,当您使用 with 时,这会自动完成

【讨论】:

  • 哇,你就是那个男人!谢谢你,格雷厄姆的解释。它就像我想要的那样工作。现在,如何在每个单词之间添加逗号?示例 sno、用户名、tweetText。
  • 取决于,这些词是由制表符划定的吗?如果他们只是调用类似 'line = re.sub('\t', ',\t', line)' 的东西,它只是用逗号替换所有制表符,然后制表符,如果它只是空格,同样的事情就可以替换''/t'' 带有空格的正则表达式
【解决方案3】:

试试这个正则表达式: clean_data=' '.join(re.sub("[@\^&\*\$]|#\S+|\S+[a-z0-9]\.(com|net|org)"," ",data).split()) # regular expression to strip the html out of the text

解释:

  • [@\^&\*\$]匹配的字符,你想替换

  • #\S+匹配哈希标签

  • \S+[a-z0-9]\.(com|net|org) 匹配域名

如果https? 无法识别 URL,您必须填写潜在 TLD 列表。

Demo

【讨论】:

  • Carsten +1 向您解释正则表达式。
猜你喜欢
  • 2014-12-01
  • 1970-01-01
  • 2011-07-11
  • 2014-06-26
  • 2021-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多