在Python中从CSV文件中读取行

73

我有一个CSV文件,以下是它的样本:

Year:  Dec: Jan:
1      50   60
2      25   50
3      30   30
4      40   20
5      10   10
我知道如何读取文件并打印每一列(例如:['Year', '1', '2', '3'等])。但我实际想做的是读取行,就像这样:['Year', 'Dec', 'Jan'],然后['1', '50', '60']等等。
之后我想把那些数字['1', '50', '60']存储到变量中,以便稍后可以对它们进行总计,例如: Year_1 = ['50', '60']。 然后我可以执行 sum(Year_1) = 110
在Python 3中,我该如何做?
10个回答

126

使用csv模块

import csv

with open("test.csv", "r") as f:
    reader = csv.reader(f, delimiter="\t")
    for i, line in enumerate(reader):
        print 'line[{}] = {}'.format(i, line)

输出:

line[0] = ['Year:', 'Dec:', 'Jan:']
line[1] = ['1', '50', '60']
line[2] = ['2', '25', '50']
line[3] = ['3', '30', '30']
line[4] = ['4', '40', '20']
line[5] = ['5', '10', '10']

1
我该如何使其分别打印每一行而不是全部在一起(例如,第0行= ['年份:','十二月:','一月:']),我尝试过print(line [0]),但它没有起作用。 - Goose
2
我在python3中遇到了以下错误:iterator should return strings, not bytes (did you open the file in text mode?),并通过将rb更改为rt来解决了它。 - J0ANMM
1
@J0ANMM 很好的指出。这个答案是在 Python 3 没有被广泛采用的时候编写的,因此隐含地针对 Python 2。我会相应地更新答案。 - Joel Cornett

44
你可以像这样做:

你可以像这样做:

with open("data1.txt") as f:
    lis = [line.split() for line in f]        # create a list of lists
    for i, x in enumerate(lis):              #print the list items 
        print "line{0} = {1}".format(i, x)

# output 
line0 = ['Year:', 'Dec:', 'Jan:']
line1 = ['1', '50', '60']
line2 = ['2', '25', '50']
line3 = ['3', '30', '30']
line4 = ['4', '40', '20']
line5 = ['5', '10', '10']

或者:

with open("data1.txt") as f:
    for i, line in enumerate(f):             
        print "line {0} = {1}".format(i, line.split())

# output         
line 0 = ['Year:', 'Dec:', 'Jan:']
line 1 = ['1', '50', '60']
line 2 = ['2', '25', '50']
line 3 = ['3', '30', '30']
line 4 = ['4', '40', '20']
line 5 = ['5', '10', '10']

编辑:

with open('data1.txt') as f:
    print "{0}".format(f.readline().split())
    for x in f:
        x = x.split()
        print "{0} = {1}".format(x[0],sum(map(int, x[1:])))

# output          
['Year:', 'Dec:', 'Jan:']
1 = 110
2 = 75
3 = 60
4 = 60
5 = 20

请查看我为@Joel Cornett的答案留下的评论。 - Goose
@Goose,你可以使用lis[0]来获取第0行,参见我的编辑答案。 - Ashwini Chaudhary
好的,现在我该如何在lis[0]中找到元素呢?例如,我需要将月份数字相加(50+60),所以对于第一年来说,它应该是110。lis[0][0]对我没有用。那就是我的主要目标。 - Goose
@Goose,请看我的编辑后的答案,你在原问题中根本没有提到这一点。 - Ashwini Chaudhary
抱歉,我以为一旦我能读取列,我就可以自己解决了。但是您编辑的方法出现了问题,我用于我的“实际”文件无法运行。请参见:http://i.imgur.com/EORK2.png。我想要做的是将每个总数存储在一个变量中,例如year1=110等等。我不仅仅是想打印出来,请原谅我当初表述不清。我当时认为这样做会更容易,对此我感到很抱歉。 - Goose
显示剩余2条评论

21

按列阅读更难吗?

无论如何,这将读取该行并将值存储在列表中:

for line in open("csvfile.csv"):
    csv_row = line.split() #returns a list ["1","50","60"]

现代解决方案:

# pip install pandas
import pandas as pd 
df = pd.read_table("csvfile.csv", sep=" ")

当我将这个实现到我的程序中时,我会收到一个错误提示:'list'对象没有'split'属性。 - Goose
这在2.7和3.3上运行得像魔法一样顺畅。 - The Unfun Cat
也许是我的文件问题,上面的文本只是一个示例,实际文件要大得多。 - Goose
大小与此无关。我们需要看到您的程序才能帮助您进一步 :) - The Unfun Cat
如果一行中的某个值包含了分割字符,那该怎么办? - Alexandre Nucera
显示剩余2条评论

8

最简单的方法是这样的:

from csv import reader

# open file in read mode
with open('file.csv', 'r') as read_obj:
    # pass the file object to reader() to get the reader object
    csv_reader = reader(read_obj)
    # Iterate over each row in the csv using reader object
    for row in csv_reader:
        # row variable is a list that represents a row in csv
        print(row)

output:
['Year:', 'Dec:', 'Jan:']
['1', '50', '60']
['2', '25', '50']
['3', '30', '30']
['4', '40', '20']
['5', '10', '10']

5
import csv

with open('filepath/filename.csv', "rt", encoding='ascii') as infile:
    read = csv.reader(infile)
    for row in read :
        print (row)

这将解决你的问题。不要忘记提供编码。

似乎访问模式不正确。应该是r+,而不是rt - mootmoot

4
#  This program reads columns in a csv file
import csv
ifile = open('years.csv', "r")
reader = csv.reader(ifile)

# initialization and declaration of variables
rownum = 0
year = 0
dec = 0
jan = 0
total_years = 0`

for row in reader:
    if rownum == 0:
        header = row  #work with header row if you like
    else:
    colnum = 0
    for col in row:
        if colnum == 0:
            year = float(col)
        if colnum == 1:
            dec = float(col)
        if colnum == 2:
            jan = float(col)
        colnum += 1
    # end of if structure

# now we can process results
if rownum != 0:
    print(year, dec, jan)
    total_years = total_years + year
    print(total_years)

# time to go after the next row/bar
rownum += 1

ifile.close()

有点晚了,但还是要提醒您... 您需要创建并标识名为 "years.csv" 的 csv 文件:

年份 十二月 一月 1 50 60 2 25 50 3 30 30 4 40 20 5 10 10


你忘记缩进 else 后面的代码块了。但是解决方案很好。 - Joey

4

例子:

import pandas as pd

data = pd.read_csv('data.csv')

# read row line by line
for d in data.values:
  # read column by index
  print(d[2])

2

csv模块按行处理csv文件。如果你想按列处理,pandas是一个不错的解决方案。

此外,有两种纯Python代码获取所有(或特定)列的方法。

1. csv.DictReader

最初的回答

with open('demo.csv') as file:
    data = {}
    for row in csv.DictReader(file):
        for key, value in row.items():
            if key not in data:
                data[key] = []
            data[key].append(value)

这很容易理解。

2. 使用zip的csv.reader

with open('demo.csv') as file:
    data = {values[0]: values[1:] for values in zip(*csv.reader(file))}

这并不是很清晰,但却很高效。 zip(x, y, z)函数可以将列表 x, y, z 进行转置。 使用*csv.reader(file)可以将列名作为参数传递给zip函数,从而创建一个类似于 (x, y, z) 的对象。

演示结果

demo.csv文件的内容如下:

a,b,c
1,2,3
4,5,6
7,8,9

1的结果为:

>>> print(data)
{'c': ['3', '6', '9'], 'b': ['2', '5', '8'], 'a': ['1', '4', '7']}

2的结果是:

>>> print(data)
{'c': ('3', '6', '9'), 'b': ('2', '5', '8'), 'a': ('1', '4', '7')}

0

可以使用 pandas 库来完成。

示例:

import numpy as np
import pandas as pd

file = r"C:\Users\unknown\Documents\Example.csv"
df1 = pd.read_csv(file)
df1.head()

0

我在这里留下我的解决方案。

import csv
import numpy as np

with open(name, newline='') as f:
    reader = csv.reader(f, delimiter=",")
    # skip header
    next(reader)
    # convert csv to list and then to np.array
    data  = np.array(list(reader))[:, 1:] # skip the first column

print(data.shape) # => (N, 2)

# sum each row
s = data.sum(axis=1)
print(s.shape) # => (N,)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接