【问题标题】:csv read columns corresponding to other columns valuescsv读取与其他列值对应的列
【发布时间】:2017-10-05 20:54:16
【问题描述】:

我需要解析一个csv 文件。

输入:文件+名称

Index   |   writer   |  year  |  words
  0     |   Philip   |  1994  | this is first row 
  1     |   Heinz    |  2000  | python is wonderful (new line) second line
  2     |   Thomas   |  1993  | i don't like this
  3     |   Heinz    |  1898  | this is another row
  .     |     .      |    .   |      .
  .     |     .      |    .   |      .
  N     |   Fritz    |  2014  | i hate man united

输出:名称对应的所有单词列表

l = ['python is wonderful second line', 'this is another row']

我尝试了什么?

import csv
import sys

class artist:
    def __init__(self, name, file):
        self.file = file 
        self.name = name
        self.list = [] 

    def extractText(self):
        with open(self.file, 'rb') as f:
            reader = csv.reader(f)
            temp = list(reader)
        k = len(temp)
        for i in range(1, k):
            s = temp[i]
            if s[1] == self.name:
                self.list.append(str(s[3]))


if __name__ == '__main__':
    # arguements
    inputFile = str(sys.argv[1])
    Heinz = artist('Heinz', inputFile)
    Heinz.extractText()
    print(Heinz.list)

输出为:

["python is wonderful\r\nsecond line", 'this is another row']

对于包含多于一行单词的单元格,我如何摆脱\r\n,并且循环非常慢,是否可以改进?

【问题讨论】:

    标签: python csv parsing python-3.5


    【解决方案1】:

    您可以简单地使用 pandas 来获取列表:

    import pandas
    df = pandas.read_csv('test1.csv')
    index = df[df['writer'] == "Heinz"].index.tolist() # get the specific name's index
    l = list()
    for i in index:
        l.append(df.iloc[i, 3].replace('\n','')) # get the cell and strip new line '\n', append to list.
    l   
    

    输出:

    ['python is wonderful second line', 'this is another row']
    

    【讨论】:

    • 这不是我想要的。我需要特定作家/艺术家的话。不是所有的词。
    • @TonyTannous 用特定作者更新了答案。
    【解决方案2】:

    摆脱s[3] 中的换行符:我建议' '.join(s[3].splitlines())。请参阅"".splitlines 的文档,另请参阅"".translate

    改进循环:

    def extractText(self):
        with open(self.file, 'rb') as f:
            for s in csv.reader(f):
                s = temp[i]
                if s[1] == self.name:
                    self.list.append(str(s[3]))
    

    这样可以节省一次数据。

    但请考虑@Tiny.D 的建议并尝试使用 pandas。

    【讨论】:

    • 但是我必须在每个对象中保留整个文本,然后再删除一些行。我不是吗?我需要特定的词而不是全部。
    • 原代码将所有文件内容复制到内存temp = list(reader);这里每行都检查 s[1] == self.name;大多数行都被丢弃了。
    【解决方案3】:

    这至少应该更快,因为您在读取文件时进行解析,然后删除不需要的回车符和换行符(如果它们存在)。

    with open(self.file) as csv_fh:
         for n in csv.reader(csv_fh):
             if n[1] == self.name:
                self.list.append(n[3].replace('\r\n', ' ')
    

    【讨论】:

      【解决方案4】:

      要折叠多个空格,您可以使用正则表达式,为了加快速度,请尝试循环理解:

      import re
      
      def extractText(self):
          RE_WHITESPACE = re.compile(r'[ \t\r\n]+')
          with open(self.file, 'rU') as f:
              reader = csv.reader(f)
      
              # skip the first line
              next(reader)
      
              # put all of the words into a list if the artist matches
              self.list = [RE_WHITESPACE.sub(' ', s[3])
                           for s in reader if s[1] == self.name]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-02-19
        • 2017-07-08
        • 1970-01-01
        • 2019-04-08
        • 2020-08-30
        • 1970-01-01
        相关资源
        最近更新 更多