Baca kolom tertentu dari file csv dengan modul csv?

176

Saya mencoba mengurai file csv dan mengekstrak data hanya dari kolom tertentu.

Contoh csv:

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

Saya mencoba untuk menangkap kolom hanya spesifik, mengatakan ID, Name, Zipdan Phone.

Kode yang saya lihat telah membuat saya percaya bahwa saya dapat memanggil kolom tertentu dengan nomor yang sesuai, jadi yaitu: Nameakan berkorespondensi dengan 2dan mengulangi setiap baris menggunakan row[2]akan menghasilkan semua item dalam kolom 2. Hanya saja tidak.

Inilah yang telah saya lakukan sejauh ini:

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

dan saya berharap ini hanya akan mencetak kolom spesifik yang saya inginkan untuk setiap baris kecuali itu tidak, saya mendapatkan kolom terakhir saja.

frankV
sumber
1
mengapa 'rb'bendera untuk open()? bukankah seharusnya sederhana r?
Elazar
7
@ Elazar: dengan Python 2 (yang digunakan OP) "rb"sesuai untuk diteruskan ke csv.reader.
DSM
Mengapa file CSV contoh Anda memperlihatkan karakter pipa sebagai pembatas tetapi kode contoh Anda menggunakan spasi?
Kelly S. French
1
@ KellyS.French Saya pikir ini akan membantu memvisualisasikan data untuk keperluan pertanyaan ini.
frankV

Jawaban:

187

Satu-satunya cara Anda akan mendapatkan kolom terakhir dari kode ini adalah jika Anda tidak memasukkan pernyataan cetak Anda dalamfor loop Anda .

Kemungkinan besar ini adalah akhir dari kode Anda:

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

Anda ingin ini:

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

Sekarang kita telah membahas kesalahan Anda, saya ingin mengambil waktu ini untuk memperkenalkan Anda ke modul panda .

Panda spektakuler untuk berurusan dengan file csv, dan kode berikut akan menjadi yang Anda butuhkan untuk membaca csv dan menyimpan seluruh kolom ke dalam variabel:

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

jadi jika Anda ingin menyimpan semua info di kolom Anda Nameske dalam variabel, ini yang perlu Anda lakukan:

names = df.Names

Ini adalah modul yang hebat dan saya sarankan Anda memeriksanya. Jika karena alasan tertentu pernyataan cetak Anda dalam forlingkaran dan itu masih hanya mencetak kolom terakhir, yang seharusnya tidak terjadi, tetapi beri tahu saya jika asumsi saya salah. Kode yang Anda kirim memiliki banyak kesalahan lekukan sehingga sulit untuk mengetahui di mana seharusnya. Semoga ini bermanfaat!

Ryan Saxe
sumber
1
Apakah mungkin untuk menghapus nomor indeks dari kueri? @Ryan Saxe
Malachi Bazar
Ya, lakukan iterate saja dalam for for loop.
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'])

Dengan file seperti

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

Akan menghasilkan

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

Atau sebagai alternatif jika Anda ingin pengindeksan numerik untuk kolom:

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

Untuk mengubah pembatas tambahkan delimiter=" "ke instantiation yang sesuai, yaitureader = csv.reader(f,delimiter=" ")

HennyH
sumber
30

Gunakan panda :

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

Buang kolom yang tidak dibutuhkan pada waktu parse:

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

PS Saya hanya mengagregasi apa yang dikatakan orang lain dengan cara sederhana. Jawaban aktual diambil dari sini dan sini .

VasiliNovikov
sumber
1
Saya pikir Panda adalah solusi yang bisa diterima. Saya sering menggunakan Panda dan sangat suka perpustakaan, tetapi pertanyaan ini secara khusus merujuk pada modul CSV.
frankV
1
@ FrankV Nah, judul, tag, dan paragraf pertama tidak melarang panda dengan cara apa pun, AFAI dapat melihatnya. Saya sebenarnya hanya berharap untuk menambahkan jawaban yang lebih sederhana untuk yang sudah dibuat di sini (jawaban lain juga menggunakan panda).
VasiliNovikov
18

Dengan panda yang dapat Anda gunakan read_csvdengan usecolsparameter:

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

Contoh:

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
ayhan
sumber
16

Anda bisa menggunakannya numpy.loadtext(filename). Misalnya jika ini adalah basis data Anda .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 |

Dan Anda menginginkan Namekolom:

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

Lebih mudah Anda dapat menggunakan genfromtext:

b = np.genfromtxt(r'filepath\name.csv', delimiter='|', names=True,dtype=None)
>>> b['Name']
array([' Adam ', ' Carl ', ' Adolf ', ' Den '], 
      dtype='|S7')
GM
sumber
@ G Apakah harus ada r di samping 'filepath \ name.csv'?
114
6

Konteks: Untuk jenis pekerjaan ini Anda harus menggunakan pustaka python petl yang menakjubkan. Itu akan menghemat banyak pekerjaan dan potensi frustrasi dari melakukan hal-hal 'secara manual' dengan modul csv standar. AFAIK, satu-satunya orang yang masih menggunakan modul csv adalah mereka yang belum menemukan alat yang lebih baik untuk bekerja dengan data tabular (panda, petl, dll.), Yang baik-baik saja, tetapi jika Anda berencana untuk bekerja dengan banyak data di Karir Anda dari berbagai sumber aneh, belajar sesuatu seperti petl adalah salah satu investasi terbaik yang dapat Anda lakukan. Untuk memulai hanya perlu waktu 30 menit setelah Anda selesai menginstal pip petl. Dokumentasinya sangat bagus.

Jawab: Katakanlah Anda memiliki tabel pertama dalam file csv (Anda juga dapat memuat langsung dari database menggunakan petl). Maka Anda cukup memuatnya dan lakukan hal berikut.

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')
PeteBeat
sumber
4

Saya pikir ada cara yang lebih mudah

import pandas as pd

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

Jadi di sini iloc[:, 0], :berarti semua nilai, 0berarti posisi kolom. dalam contoh di bawah IDini akan dipilih

ID | Name | Address | City | State | Zip | Phone | OPEID | IPEDS |
10 | C... | 130 W.. | Mo.. | AL... | 3.. | 334.. | 01023 | 10063 |
Nuriddin Kudratov
sumber
Jika berhasil
kawan
3
import pandas as pd 
csv_file = pd.read_csv("file.csv") 
column_val_list = csv_file.column_name._ndarray_values
Hari K.
sumber
Anda harus pip install pandasterlebih dahulu
Boris
1

Berkat cara Anda dapat mengindeks dan mengatur ulang kerangka data panda, cara yang sangat mudah untuk mengekstrak satu kolom dari file csv ke dalam variabel adalah:

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

Beberapa hal yang perlu dipertimbangkan:

Cuplikan di atas akan menghasilkan panda Seriesdan tidak dataframe. Saran dari ayhan with usecolsjuga akan lebih cepat jika kecepatan menjadi masalah. Menguji dua pendekatan yang berbeda menggunakan %timeitfile csv berukuran 2122 KB menghasilkan 22.8 msuntuk pendekatan usecols dan 53 msuntuk pendekatan yang saya sarankan.

Dan jangan lupa import pandas as pd

vestland
sumber
0

Jika Anda perlu memproses kolom secara terpisah, saya ingin merusak kolom dengan zip(*iterable)pola (secara efektif "unzip"). Jadi untuk contoh Anda:

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

Untuk mengambil nama kolom , daripada menggunakan readlines () lebih baik gunakan readline () untuk menghindari loop & membaca file lengkap & menyimpannya dalam array.

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

    # get number of columns

    line = csvfile.readline()

    first_item = line.split(',')
Suren
sumber