Прочитать конкретные столбцы из файла csv с помощью модуля csv?
Я пытаюсь проанализировать файл csv и извлечь данные только из определенных столбцов.
Пример csv:
ID | Name | Address | City | State | Zip | Phone | OPEID | IPEDS |
10 | C... | 130 W.. | Mo.. | AL... | 3.. | 334.. | 01023 | 10063 |
Я пытаюсь захватить только определенные столбцы, например ID
, Name
, Zip
и Phone
.
Код, на который я смотрел, привел меня к мысли, что я могу вызвать конкретный столбец по его соответствующему номеру, так что: Name
будет соответствовать 2
, и итерация по каждой строке с помощью row[2]
приведет к созданию всех пункты в столбце 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
Единственный способ получить последний столбец из этого кода - это если вы не включаете свой оператор печати в в цикл 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.
Pandas является впечатляющим для работы с csv файлами, и следующий код будет всем, что вам нужно, чтобы прочитать 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 = df.Names
Это отличный модуль, и я предлагаю вам изучить его. Если по какой-то причине ваш оператор печати находился в цикле for
, и он все еще печатал только последний столбец, чего не должно было случиться, но дайте мне знать, ошибочно ли было мое предположение. У вашего опубликованного кода много ошибок в отступе, поэтому было трудно понять, что должно было быть где. Надеюсь, это было полезно!
Ответ 2
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)
reader.next()
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=" ")
Ответ 3
Используйте панд:
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'])
PS Я просто обобщаю то, что говорили другие, в простой форме. Актуальные ответы взяты здесь и здесь.
Ответ 4
Вы можете использовать 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')
Ответ 5
С pandas вы можете использовать read_csv
с параметром usecols
:
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
Ответ 6
Контекст. Для этого типа работы вы должны использовать удивительную библиотеку python petl. Это сэкономит вам много работы и потенциального разочарования в том, что вы делаете "вручную" со стандартным модулем csv. AFAIK, единственные люди, которые до сих пор используют модуль csv, - это те, кто еще не нашел лучших инструментов для работы с табличными данными (pandas, petl и т.д.), Что хорошо, но если вы планируете работать с большим количеством данные в вашей карьере из разных странных источников, изучение чего-то вроде petl - одна из лучших инвестиций, которую вы можете сделать. Чтобы начать работу, вы должны пройти всего 30 минут после того, как вы закончили pip install petl. Документация отличная.
Ответ: предположим, что у вас есть первая таблица в файле 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')
Ответ 7
Чтобы получить имя столбца, вместо использования readlines() лучше использовать readline(), чтобы избежать цикла и чтения полного файла и сохранения это в массиве.
with open(csv_file, 'rb') as csvfile:
# get number of columns
line = csvfile.readline()
first_item = line.split(',')
Ответ 8
Благодаря тому, что вы можете индексировать и размещать данные в фрейме pandas, очень простой способ извлечь один столбец из файла CSV в переменную:
myVar = pd.read_csv('YourPath', sep = ",")['ColumnName']
Несколько вещей для рассмотрения:
Приведенный выше фрагмент создаст Series
панд, а не dataframe
. Предложение от usecols
с usecols
также будет быстрее, если скорость является проблемой. Тестирование двух разных подходов с использованием %timeit
для csv файла размером 2122 КБ дает 22.8 ms
для подхода usecols и 53 ms
для предложенного мной подхода.
И не забудьте import pandas as pd
Ответ 9
Если вам нужно обрабатывать столбцы по отдельности, мне нравится деструктурировать столбцы с помощью шаблона zip(*iterable)
(фактически "unzip"). Итак, для вашего примера:
ids, names, zips, phones = zip(*(
(row[1], row[2], row[6], row[7])
for row in reader
))
Ответ 10
Считайте CSV в кадр данных pandas
, у pandas есть встроенная функция для транспонирования, которая может быть вызвана, как показано ниже.
import pandas as pd
csv = pd.read_csv("test.csv", skiprows=1)
# use skiprows if you want to skip headers
df_csv = pd.DataFrame(data=csv)
transposed_csv = df_csv.T