Đọc các cột cụ thể từ tệp csv với mô-đun csv?


176

Tôi đang cố phân tích cú pháp thông qua tệp csv và trích xuất dữ liệu từ các cột cụ thể.

Ví dụ csv:

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

Tôi đang cố gắng để nắm bắt các cột chỉ cụ thể, nói ID, Name, ZipPhone.

Mã tôi đã xem đã khiến tôi tin rằng tôi có thể gọi cột cụ thể theo số tương ứng của nó, do đó: Namesẽ tương ứng 2và lặp qua từng hàng bằng cách sử dụng row[2]sẽ tạo ra tất cả các mục trong cột 2. Chỉ có nó không có.

Đây là những gì tôi đã làm cho đến nay:

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

và tôi hy vọng rằng điều này sẽ chỉ in ra các cột cụ thể mà tôi muốn cho mỗi hàng trừ khi không có, tôi chỉ nhận được cột cuối cùng.


1
Tại sao 'rb'cờ đến open()? nó không nên đơn giản r?
Elazar

7
@Elazar: trong Python 2 (mà OP đang sử dụng) "rb"phù hợp để chuyển đến csv.reader.
DSM

Tại sao tệp CSV mẫu của bạn hiển thị ký tự ống là dấu phân cách nhưng mã ví dụ của bạn sử dụng khoảng trắng?
Kelly S. Pháp

1
@ KellyS.Fbler Tôi nghĩ rằng nó sẽ giúp trực quan hóa dữ liệu cho các mục đích của câu hỏi này.
thẳng thắn

Câu trả lời:


187

Cách duy nhất bạn sẽ nhận được cột cuối cùng từ mã này là nếu bạn không bao gồm câu lệnh in của mình trongfor vòng lặp.

Đây rất có thể là phần cuối của mã của bạn:

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

Bạn muốn nó là thế này:

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

Bây giờ chúng tôi đã che đậy lỗi lầm của bạn, tôi muốn dành thời gian này để giới thiệu cho bạn mô-đun gấu trúc .

Pandas là ngoạn mục để xử lý các tệp csv và mã sau đây sẽ là tất cả những gì bạn cần để đọc một csv và lưu toàn bộ một cột vào một biến:

import pandas as pd
df = pd.read_csv(csv_file)
saved_column = df.column_name #you can also use df['column_name']

Vì vậy, nếu bạn muốn lưu tất cả thông tin trong cột của mình Namesvào một biến, đây là tất cả những gì bạn cần làm:

names = df.Names

Đó là một mô-đun tuyệt vời và tôi khuyên bạn nên xem xét nó. Nếu vì một lý do nào đó, câu lệnh in của bạn bị forlặp và nó vẫn chỉ in ra cột cuối cùng, điều đó không nên xảy ra, nhưng hãy cho tôi biết nếu giả định của tôi sai. Mã được đăng của bạn có rất nhiều lỗi thụt lề nên thật khó để biết những gì được cho là ở đâu. Hy vọng điều này là hữu ích!


1
Có thể loại bỏ các số chỉ mục từ truy vấn? @Ryan Saxe
Malachi Bazar

Vâng, chỉ cần lặp qua nó trong một vòng lặp for.
davegallant

109
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'])

Với một tập tin như

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

Sẽ xuất

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

Hoặc cách khác nếu bạn muốn lập chỉ mục số cho các cột:

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']

Để thay đổi dấu phân cách thêm delimiter=" "vào phần khởi tạo thích hợp, nghĩa làreader = csv.reader(f,delimiter=" ")


30

Sử dụng gấu trúc :

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

Hủy các cột không cần thiết tại thời điểm phân tích cú pháp:

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

Tái bút: Tôi chỉ tổng hợp những gì người khác đã nói một cách đơn giản. Câu trả lời thực tế được lấy từ đâyđây .


1
Tôi nghĩ Pandas là một giải pháp hoàn toàn chấp nhận được. Tôi sử dụng Pandas thường xuyên và thực sự thích thư viện, nhưng câu hỏi này đặc biệt tham chiếu mô-đun CSV.
thẳng thắn

1
@frankV Chà, tiêu đề, các thẻ và đoạn đầu tiên không cấm gấu trúc dưới bất kỳ hình thức nào, AFAI có thể thấy. Tôi thực sự chỉ hy vọng sẽ thêm một câu trả lời đơn giản hơn cho những câu đã được thực hiện ở đây (các câu trả lời khác cũng sử dụng gấu trúc).
VasiliNovikov

18

Với gấu trúc bạn có thể sử dụng read_csvvới usecolstham số:

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

Thí dụ:

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

16

Bạn có thể sử dụng numpy.loadtext(filename). Ví dụ: nếu đây là cơ sở dữ liệu của bạn .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 |

Và bạn muốn Namecột:

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')

Dễ dàng hơn bạn có thể sử dụng genfromtext:

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

@G Có nghĩa là có một r bên cạnh 'filepath \ name.csv'?
114

6

Bối cảnh: Đối với loại công việc này, bạn nên sử dụng thư viện petl python tuyệt vời. Điều đó sẽ giúp bạn tiết kiệm rất nhiều công việc và khả năng thất vọng khi thực hiện mọi thứ 'thủ công' với mô-đun csv tiêu chuẩn. AFAIK, những người duy nhất vẫn sử dụng mô-đun csv là những người chưa khám phá ra các công cụ tốt hơn để làm việc với dữ liệu dạng bảng (gấu trúc, petl, v.v.), điều này tốt, nhưng nếu bạn có kế hoạch làm việc với nhiều dữ liệu trong sự nghiệp của bạn từ nhiều nguồn lạ khác nhau, học một cái gì đó như petl là một trong những khoản đầu tư tốt nhất bạn có thể thực hiện. Để bắt đầu, chỉ mất 30 phút sau khi bạn cài đặt xong petl. Các tài liệu là tuyệt vời.

Trả lời: Giả sử bạn có bảng đầu tiên trong tệp csv (bạn cũng có thể tải trực tiếp từ cơ sở dữ liệu bằng petl). Sau đó, bạn chỉ cần tải nó và làm như sau.

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

Tôi nghĩ có một cách dễ dàng hơn

import pandas as pd

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

Vì vậy, ở đây iloc[:, 0], :có nghĩa là tất cả các giá trị, 0có nghĩa là vị trí của cột. trong ví dụ dưới đây IDsẽ được chọn

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

Nếu nó hoạt động được mọi người, xin vui lòng upvote, cho người khác biết điều đó :)
Nuriddin Kudratov

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

Bạn sẽ phải pip install pandasđầu tiên
Boris

1

Nhờ vào cách bạn có thể lập chỉ mục và tập hợp một khung dữ liệu gấu trúc, một cách rất dễ dàng để trích xuất một cột từ tệp csv thành một biến là:

myVar = pd.read_csv('YourPath', sep = ",")['ColumnName']

Một vài điều cần xem xét:

Đoạn trích trên sẽ tạo ra một con gấu trúc Seriesvà không dataframe. Gợi ý từ ayhan usecolscũng sẽ nhanh hơn nếu tốc độ là một vấn đề. Thử nghiệm hai cách tiếp cận khác nhau bằng cách sử dụng %timeittệp csv có kích thước 2122 KB 22.8 mscho phương pháp usecols và 53 msphương pháp tiếp cận được đề xuất của tôi.

Và đừng quên import pandas as pd


0

Nếu bạn cần xử lý các cột riêng biệt, tôi muốn cấu trúc các cột bằng zip(*iterable)mẫu ("giải nén" một cách hiệu quả). Vì vậy, ví dụ của bạn:

ids, names, zips, phones = zip(*(
  (row[1], row[2], row[6], row[7])
  for row in reader
))

-1

Để tìm nạp tên cột , thay vì sử dụng readline () tốt hơn nên sử dụng readline () để tránh vòng lặp & đọc tệp hoàn chỉnh và lưu trữ nó trong mảng.

with open(csv_file, 'rb') as csvfile:

    # get number of columns

    line = csvfile.readline()

    first_item = line.split(',')
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.