【问题标题】:Reading csv file twice in python在python中两次读取csv文件
【发布时间】:2017-09-06 20:06:10
【问题描述】:

这是我的 Python 代码:

import csv

# Reading
ordersFile = open('orders.csv', 'rb')
ordersR = csv.reader(ordersFile, delimiter=',')

# Find order employeeID=5, shipCountry="Brazil"
print "Find order employeeID=5, shipCountry=\"Brazil\""
for order in ordersR:
    if order[2] == '5' and order[13] == 'Brazil':
        print order
# Find order employeeID=5
print "Find order employeeID=5"
for order in ordersR:
    if order[2] == '5':
        print order
ordersFile.close()

我可以打印一些“# Find order employeeID=5, shipCountry="Brazil"”,但我没有得到 # Find order employeeID=5 的结果。我在考虑如何多次读取(选择)同一个 csv 文件中的行。

【问题讨论】:

  • 您不能两次读取同一个打开的文件。在第二次阅读之前将其倒回,或者关闭并再次打开。更好的是,在您第一次阅读文件时计算您需要的所有内容。
  • 你试过ordersFile.seek(0)吗?

标签: python python-2.7 csv


【解决方案1】:

您只是直接阅读 CSV 文件,但如果您想多次处理数据,则应将内容读入变量。这样您就不必在每次需要对其进行处理时重新读取该文件。

import csv

# Read order rows into our list
# Here I use a context manager so that the file is automatically
# closed upon exit
with open('orders.csv') as orders_file:
    reader = csv.reader(orders_file, delimiter=',')
    orders = list(reader)

# Find order employeeID=5, shipCountry="Brazil"
print "Find order employeeID=5, shipCountry=\"Brazil\""
for order in orders:
    if order[2] == '5' and order[13] == 'Brazil':
        print order

# Find order employeeID=5
print "Find order employeeID=5"
for order in orders:
    if order[2] == '5':
        print order

如果您的 CSV 文件太大而无法放入内存(或者您出于某种原因不想将其全部读入内存),那么您将需要一种不同的方法。如果您需要,请发表评论。

【讨论】:

  • 不是for row in reader:orders.extend(row) 只是orders=list(reader)
  • @birryree 谢谢,你能分享一下不同的方法吗?
  • @user6142261 - 你会说你所有的东西都可以一次性完成(如果是这样,其他答案已经涵盖了)?您不想将所有内容读入内存吗?您是否愿意使用第三方库?你有 巨大的 CSV 文件吗?
【解决方案2】:

最好将文件读一遍,因为 I/O 可能是程序中最慢的部分。

如果您需要重新读取文件,您可以关闭它然后重新打开它,或者将seek() 放在开头,即在循环之间添加ordersFile.seek(0)

【讨论】:

    【解决方案3】:

    您可以做的只是将阅读器对象结果转换为列表:

    with open('orders.csv', 'rb') as ordersFile:
        ordersR = list(csv.reader(ordersFile, delimiter=','))
    

    阅读器对象就像一个生成器,一旦你迭代了值,你就不能开始第二个循环来再次读取值。

    【讨论】:

      【解决方案4】:

      如果您不想将所有数据存储在一个列表中,这是一种纯基于生成器的方法,可以对 csv 文件进行两次迭代。使用itertools.tee:

      with open('orders.csv', 'r') as file:
          rows0, rows1 = tee(reader(file, delimiter=','))
      
          for row in rows0:
              print(row)  # search for something...
      
          print()
      
          for row in rows1:
              print(row)  # search for a different thing...
      

      【讨论】:

        【解决方案5】:

        这是使用 pandas 模块的好案例(您需要安装它:pip install pandas

        之后,您只需读取一次文件,即可轻松执行任何类型的拟合

        例如,要多次读取和过滤文件,请遵循以下示例:

        import pandas as pd 
        
        # read csv into a dataframe 
        df = pd.read_csv('orders.csv', delimiter=',') 
        
        # get the data that has employeeID == 5
        df1 = df[df["employeeID"] == 5]
        print(df1) 
        
        # get the data that has employeeID == 5 and  shipCountry=\"Brazil\"
        
        df2 = df[(df["employeeID"] == 5)& (df["shipCountry"] == "Brazil")]
        print(df2) 
        

        【讨论】:

          【解决方案6】:

          正如上面提到的@Nick T,与 RAM 访问相比,I/O 被认为是昂贵的,因此如果您需要多次迭代文件,最好将其保存到变量中.

          您还可以在单​​个 for 循环中组合多个条件,因此它执行得更快(单次迭代):

          with open('orders.csv', 'rb') as ordersFile:
              orders = list(csv.reader(ordersFile, delimiter=','))
          
          # Find order employeeID=5, shipCountry="Brazil"
          emp = []
          country = []
          for order in orders:
              if order[2] == '5':
                  if order[13] == 'Brazil':
                      country.append(order)
                  else:
                      emp.append(order)
          
           print 'emp id=5 and shippingcountry=Brazil: {}'.format(country)
           print 'emp id=5: {}'.format(emp)
          

          请注意,这是不可扩展的,您可能不想在此块中添加更多 if 逻辑,因为它变得不可读

          【讨论】:

            猜你喜欢
            • 2015-07-21
            • 1970-01-01
            • 2017-05-17
            • 2021-12-08
            • 1970-01-01
            • 1970-01-01
            • 2018-01-08
            • 2022-01-16
            • 1970-01-01
            相关资源
            最近更新 更多