如何使用csv模块从csv文件中读取特定的列?

217

我试图解析一个CSV文件,并从特定的列中提取数据。

示例CSV:

I'm trying to parse through a csv file and extract the data from only specific columns.

Example csv:

ID | Name | Address | City | State | Zip | Phone | OPEID | IPEDS |
10 | C... | 130 W.. | Mo.. | AL... | 3.. | 334.. | 01023 | 10063 |

我想只获取特定的列,比如说IDNameZip以及Phone

我查看了相关代码后相信我可以通过对应列的编号来调用特定的列,例如:Name 对应 2,然后通过使用 row[2] 遍历每一行就会产生第二列的所有项目。但实际上并不是这样的。

目前我已经做的:

import sys, argparse, csv
from settings import *

# command arguments
parser = argparse.ArgumentParser(description='csv to postgres',\
 fromfile_prefix_chars="@" )
parser.add_argument('file', help='csv file to import', action='store')
args = parser.parse_args()
csv_file = args.file

# open csv file
with open(csv_file, 'rb') as csvfile:

    # get number of columns
    for line in csvfile.readlines():
        array = line.split(',')
        first_item = array[0]

    num_columns = len(array)
    csvfile.seek(0)

    reader = csv.reader(csvfile, delimiter=' ')
        included_cols = [1, 2, 6, 7]

    for row in reader:
            content = list(row[i] for i in included_cols)
            print content

我期望它会按照要求输出每一行中我所需的列,但实际并没有,只输出了最后一列。


1
为什么在open()函数中要使用'rb'标志?应该不是简单的r吗? - Elazar
7
在Python 2中(OP正在使用),将“rb”传递给csv.reader是合适的。 - DSM
为什么你的示例CSV文件显示管道字符作为分隔符,但是你的示例代码使用空格? - Kelly S. French
2
@KellyS.French 我认为这会有助于可视化数据,以便回答这个问题。 - frankV
15个回答

224

如果你没有把你的打印语句放在for循环中,那么你唯一能够从这段代码获取到最后一列的数据。

这很可能是你代码的结尾:

for row in reader:
    content = list(row[i] for i in included_cols)
print content
您希望它变成这样:
for row in reader:
        content = list(row[i] for i in included_cols)
        print content
现在我们已经讨论了你的错误,我想花些时间向您介绍 pandas 模块。
对于处理 CSV 文件,Pandas非常出色。以下代码是您仅需读取CSV文件并将整列保存到一个变量中所需要的全部内容:
import pandas as pd
df = pd.read_csv(csv_file)
saved_column = df.column_name #you can also use df['column_name']

所以,如果你想要将你的列Names中的所有信息保存到一个变量中,这就是你需要做的全部内容:

那么,如果您想将列Names中的所有信息保存到变量中,您只需要执行以下操作:

names = df.Names

这是一个很棒的模块,我建议你研究一下。如果由于某些原因,您的打印语句在for循环中,并且仍然只打印出最后一列,这不应该发生,但如果我的假设是错误的,请告诉我。您发布的代码有很多缩进错误,因此很难知道应该放在哪里。希望这对你有所帮助!


1
是否有可能从查询中删除索引号?@Ryan Saxe - Malachi Bazar
是的,只需在for循环中遍历它。 - davegallant
既然我们已经讨论了你的错误,我想现在是介绍pandas模块的好时机。啊,没错,只有使用过Pandas,你才算真正掌握了Python! - als0052

131
import csv
from collections import defaultdict

columns = defaultdict(list) # each value in each column is appended to a list

with open('file.txt') as f:
    reader = csv.DictReader(f) # read rows into a dictionary format
    for row in reader: # read a row as {column1: value1, column2: value2,...}
        for (k,v) in row.items(): # go over each column name and value 
            columns[k].append(v) # append the value into the appropriate list
                                 # based on column name k

print(columns['name'])
print(columns['phone'])
print(columns['street'])
      

有一个文件,例如

name,phone,street
Bob,0893,32 Silly
James,000,400 McHilly
Smithers,4442,23 Looped St.

将输出

>>> 
['Bob', 'James', 'Smithers']
['0893', '000', '4442']
['32 Silly', '400 McHilly', '23 Looped St.']

或者,如果您想为列使用数字索引:

with open('file.txt') as f:
    reader = csv.reader(f)
    next(reader)
    for row in reader:
        for (i,v) in enumerate(row):
            columns[i].append(v)
print(columns[0])

>>> 
['Bob', 'James', 'Smithers']

要更改分隔符,请在适当的实例化中添加delimiter=" ",例如:reader = csv.reader(f,delimiter=" ")


35

使用pandas

import pandas as pd
my_csv = pd.read_csv(filename)
column = my_csv.column_name
# you can also use my_csv['column_name']

在解析时丢弃不必要的列:

my_filtered_csv = pd.read_csv(filename, usecols=['col1', 'col3', 'col7'])

P.S. 我只是将其他人的答案简单汇总而已。实际答案来自这里这里


2
我认为Pandas是一个完全可以接受的解决方案。我经常使用Pandas并且非常喜欢这个库,但是这个问题特别提到了CSV模块。 - frankV
1
@frankV 嗯,就我所看到的,标题、标签和第一段并没有以任何方式禁止使用pandas。实际上,我只是希望在这里已经给出的答案中添加一个更简单的答案(其他答案也使用了pandas)。 - VasiliNovikov

22
你可以使用numpy.loadtext(filename)。例如,如果这是你的数据库.csv文件:
ID | Name | Address | City | State | Zip | Phone | OPEID | IPEDS |
10 | Adam | 130 W.. | Mo.. | AL... | 3.. | 334.. | 01023 | 10063 |
10 | Carl | 130 W.. | Mo.. | AL... | 3.. | 334.. | 01023 | 10063 |
10 | Adolf | 130 W.. | Mo.. | AL... | 3.. | 334.. | 01023 | 10063 |
10 | Den | 130 W.. | Mo.. | AL... | 3.. | 334.. | 01023 | 10063 |

如果您想获取Name列:

import numpy as np 
b=np.loadtxt(r'filepath\name.csv',dtype=str,delimiter='|',skiprows=1,usecols=(1,))

>>> b
array([' Adam ', ' Carl ', ' Adolf ', ' Den '], 
      dtype='|S7')

更容易使用genfromtext
b = np.genfromtxt(r'filepath\name.csv', delimiter='|', names=True,dtype=None)
>>> b['Name']
array([' Adam ', ' Carl ', ' Adolf ', ' Den '], 
      dtype='|S7')

@G 'filepath\name.csv' 旁边应该有一个 r 吗? - 114

19

使用 pandas,您可以使用带有 usecols 参数的 read_csv

df = pd.read_csv(filename, usecols=['col1', 'col3', 'col7'])

例子:

import pandas as pd
import io

s = '''
total_bill,tip,sex,smoker,day,time,size
16.99,1.01,Female,No,Sun,Dinner,2
10.34,1.66,Male,No,Sun,Dinner,3
21.01,3.5,Male,No,Sun,Dinner,3
'''

df = pd.read_csv(io.StringIO(s), usecols=['total_bill', 'day', 'size'])
print(df)

   total_bill  day  size
0       16.99  Sun     2
1       10.34  Sun     3
2       21.01  Sun     3

7

背景:如果您要处理这种类型的工作,建议使用出色的Python Petl库。这将节省您大量手动编写标准csv模块代码的时间,并避免潜在的沮丧。据我所知,现在只有那些还没有发现更好的处理表格数据的工具(如pandas、petl等)才会继续使用csv模块,这也没什么问题;但是,如果您计划在职业生涯中处理来自各种奇怪数据源的大量数据,学习petl之类的工具是您最佳的投资之一。只需要安装petl后,30分钟就可以开始学习,文档非常优秀。

回答:假设您有一个csv文件中的第一个表格(也可以直接使用Petl从数据库加载),然后您只需加载它并执行以下操作即可。

from petl import fromcsv, look, cut, tocsv 

#Load the table
table1 = fromcsv('table1.csv')
# Alter the colums
table2 = cut(table1, 'Song_Name','Artist_ID')
#have a quick look to make sure things are ok. Prints a nicely formatted table to your console
print look(table2)
# Save to new file
tocsv(table2, 'new.csv')

5
我认为有一种更简单的方法。
import pandas as pd

dataset = pd.read_csv('table1.csv')
ftCol = dataset.iloc[:, 0].values

在这里,iloc[:, 0] 中,: 代表所有值,0 代表列的位置。

在下面的例子中,将选择 ID 列。
ID | Name | Address | City | State | Zip | Phone | OPEID | IPEDS |
10 | C... | 130 W.. | Mo.. | AL... | 3.. | 334.. | 01023 | 10063 |

3
import pandas as pd 
csv_file = pd.read_csv("file.csv") 
column_val_list = csv_file.column_name._ndarray_values

你需要先执行 pip install pandas - user3064538

1

CSV文件读写中,您可以导入csv并使用以下代码:

with open('names.csv', newline='') as csvfile:
    reader = csv.DictReader(csvfile)
    for row in reader:
        print(row['first_name'], row['last_name'])

1
import pandas as pd

dataset = pd.read_csv('Train.csv')
X = dataset.iloc[:, 1:-1].values
y = dataset.iloc[:, -1].values
  • X 是一组列,如果您想读取多个列,请使用它
  • y 是单个列,如果您想读取一个列,请使用它
  • [:, 1:-1] 表示 [行索引:到行索引, 列索引:到列索引]

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