我有一个csv文件,如下所示:
+-----+-----+-----+-----+-----+-----+-----+-----+ | AAA | bbb | ccc | DDD | eee | FFF | GGG | hhh | +-----+-----+-----+-----+-----+-----+-----+-----+ | 1 | 2 | 3 | 4 | 50 | 3 | 20 | 4 | | 2 | 1 | 3 | 5 | 24 | 2 | 23 | 5 | | 4 | 1 | 3 | 6 | 34 | 1 | 22 | 5 | | 2 | 1 | 3 | 5 | 24 | 2 | 23 | 5 | | 2 | 1 | 3 | 5 | 24 | 2 | 23 | 5 | +-----+-----+-----+-----+-----+-----+-----+-----+
...
我怎样才能在python中读取“AAA,DDD,FFF,GGG”列并跳过标题? 我想要的输出是一个如下所示的元组列表: [(1,4,3,20),(2,5,2,23),(4,6,1,22)。我想稍后将这些数据写入SQL数据库。
我提到了这篇文章:Read specific columns from a csv file with csv module?。 但我不认为这对我的情况有帮助。由于我的.csv对于大量的列非常大,我希望我能告诉python我想要的列名,所以python可以逐行读取特定的列。
答案 0 :(得分:5)
def read_csv(file, columns, type_name="Row"):
try:
row_type = namedtuple(type_name, columns)
except ValueError:
row_type = tuple
rows = iter(csv.reader(file))
header = rows.next()
mapping = [header.index(x) for x in columns]
for row in rows:
row = row_type(*[row[i] for i in mapping])
yield row
示例:
>>> import csv
>>> from collections import namedtuple
>>> from StringIO import StringIO
>>> def read_csv(file, columns, type_name="Row"):
... try:
... row_type = namedtuple(type_name, columns)
... except ValueError:
... row_type = tuple
... rows = iter(csv.reader(file))
... header = rows.next()
... mapping = [header.index(x) for x in columns]
... for row in rows:
... row = row_type(*[row[i] for i in mapping])
... yield row
...
>>> testdata = """\
... AAA,bbb,ccc,DDD,eee,FFF,GGG,hhh
... 1,2,3,4,50,3,20,4
... 2,1,3,5,24,2,23,5
... 4,1,3,6,34,1,22,5
... 2,1,3,5,24,2,23,5
... 2,1,3,5,24,2,23,5
... """
>>> testfile = StringIO(testdata)
>>> for row in read_csv(testfile, "AAA GGG DDD".split()):
... print row
...
Row(AAA='1', GGG='20', DDD='4')
Row(AAA='2', GGG='23', DDD='5')
Row(AAA='4', GGG='22', DDD='6')
Row(AAA='2', GGG='23', DDD='5')
Row(AAA='2', GGG='23', DDD='5')
答案 1 :(得分:5)
我意识到答案已被接受,但如果你真的想从csv文件中读取特定的命名列,你应该使用DictReader
(如果你没有使用{ {1}}即是。
Pandas
输出:
import csv
from StringIO import StringIO
columns = 'AAA,DDD,FFF,GGG'.split(',')
testdata ='''\
AAA,bbb,ccc,DDD,eee,FFF,GGG,hhh
1,2,3,4,50,3,20,4
2,1,3,5,24,2,23,5
4,1,3,6,34,1,22,5
2,1,3,5,24,2,23,5
2,1,3,5,24,2,23,5
'''
reader = csv.DictReader(StringIO(testdata))
desired_cols = (tuple(row[col] for col in columns) for row in reader)
答案 2 :(得分:1)
import csv
DESIRED_COLUMNS = ('AAA','DDD','FFF','GGG')
f = open("myfile.csv")
reader = csv.reader(f)
headers = None
results = []
for row in reader:
if not headers:
headers = []
for i, col in enumerate(row):
if col in DESIRED_COLUMNS:
# Store the index of the cols of interest
headers.append(i)
else:
results.append(tuple([row[i] for i in headers]))
print results
答案 3 :(得分:1)
上下文:对于这种类型的工作,你应该使用惊人的python petl库。这将为您节省大量工作和潜在的挫败感,而不是手工制作。使用标准的csv模块。 AFAIK,唯一仍然使用csv模块的人是那些还没有发现更好的工具来处理表格数据(pandas,petl等)的人,这很好,但是如果你计划使用大量的数据你的职业生涯来自各种奇怪的来源,学习像petl这样的东西是你可以做的最好的投资之一。要开始使用,只需要在完成pip install 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')
答案 4 :(得分:0)
如果您的文件和要求相对简单并且已设置,那么一旦您知道所需的列,我可能会使用split()将每个数据行划分为列条目列表:
alist = aline.split('|')
然后我会使用所需的列索引从列表中获取列条目,使用strip()处理每个列条目以删除空格,将其转换为所需的格式(看起来您的数据具有整数值),然后创建元组。
正如我所说,我假设您的要求相对固定。它们越复杂或者它们可能变得越多,就越有可能值得花时间去挑选和使用用于操纵这类数据的库。
答案 5 :(得分:0)
所有其他答案都很好,但我认为最好不要同时加载所有数据,因为csv文件可能非常庞大。我建议使用发电机。
def read_csv(f, cols):
reader = csv.reader(f)
for row in reader:
if len(row) == 1:
columns = row[0].split()
yield (columns[c] for c in cols)
在
之后可用于for循环with open('path/to/test.csv', 'rb') as f:
for bbb, ccc in read_csv(f, [1, 2]):
print bbb, ccc
当然,您可以增强此功能以接收列的名称而不是索引。要做到这一点,只需混合布拉德M回答我的。
答案 6 :(得分:0)
我认为这会有所帮助。
CSV
1997,Ford,E350,"ac, abs, moon",3000.00
1999,Chevy,"Venture ""Extended Edition""","",4900.00
1996,Jeep,Grand Cherokee,"MUST SELL! air, moon roof, loaded",4799.00
码
import csv
def get_csv(file_name, names=None, usecols=None, mode='r', encoding="utf8",
quoting=csv.QUOTE_ALL,
delimiter=',',
as_obj=False):
class RowObject:
def __init__(self, **entries):
self.__dict__.update(entries)
with open(file_name, mode=mode, encoding=encoding) as csvfile:
data_reader = csv.reader(csvfile, quoting=quoting, delimiter=delimiter)
for row in data_reader:
if usecols and names:
q = dict(zip(names, (row[i] for i in usecols)))
yield q if not as_obj else RowObject(**q)
elif usecols and not names:
yield list(row[i] for i in usecols)
elif names and not usecols:
q = dict(zip(names, (row[k] for k, i in enumerate(row))))
yield q if not as_obj else RowObject(**q)
else:
yield row
例如
filename = "/csv_exe/csv.csv"
vs = get_csv(filename, names=('f1', 'f2', 'f3', 'f4', 'f5'))
for item in vs:
print(item)
结果
{'f1': '1997', 'f4': 'ac, abs, moon', 'f3': 'E350', 'f2': 'Ford', 'f5': '3000.00'}
{'f1': '1999', 'f4': '', 'f3': 'Venture "Extended Edition"', 'f2': 'Chevy', 'f5': '4900.00'}
{'f1': '1996', 'f4': 'MUST SELL! air, moon roof, loaded', 'f3': 'Grand Cherokee', 'f2': 'Jeep', 'f5': '4799.00'}
示例2
vs = get_csv(filename, names=('f1', 'f2'), usecols=(0, 4))
RESULT2
{'f1': '1997', 'f2': '3000.00'}
{'f1': '1999', 'f2': '4900.00'}
{'f1': '1996', 'f2': '4799.00'}
示例3
vs = get_csv(filename, names=('f1', 'f2'), usecols=(0, 2), as_obj=True)
result3
<__main__.get_csv.<locals>.RowObject object at 0x01408ED0>
<__main__.get_csv.<locals>.RowObject object at 0x01408E90>
<__main__.get_csv.<locals>.RowObject object at 0x01408F10>
for item in vs:
print(item.f2)
E350
Venture "Extended Edition"
Grand Cheroke