อ่านคอลัมน์เฉพาะจากไฟล์ csv ด้วยโมดูล csv?


176

ฉันพยายามแยกวิเคราะห์ไฟล์ csv และดึงข้อมูลจากคอลัมน์เฉพาะเท่านั้น

ตัวอย่าง csv:

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

ฉันพยายามที่จะจับภาพเฉพาะคอลัมน์เฉพาะการพูดID, Name, และZipPhone

รหัสที่ฉันได้ดูทำให้ฉันเชื่อว่าฉันสามารถเรียกคอลัมน์ที่ระบุตามหมายเลขที่สอดคล้องกันได้เช่น: 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
ทำไม'rb'ธงopen()? มันควรจะง่ายrหรือไม่?
Elazar

7
@Elazar: ในหลาม 2 (ซึ่ง OP จะใช้) มีความเหมาะสมสำหรับการส่งผ่านไปยัง"rb" csv.reader
DSM

ทำไมไฟล์ CSV ตัวอย่างของคุณแสดงอักขระไพพ์เป็นตัวคั่น แต่โค้ดตัวอย่างของคุณใช้ช่องว่าง
Kelly S. French

1
@ KellyS.French ฉันคิดว่ามันจะช่วยให้เห็นภาพข้อมูลเพื่อจุดประสงค์ของคำถามนี้
frankV

คำตอบ:


187

วิธีเดียวที่คุณจะได้รับคอลัมน์สุดท้ายจากรหัสนี้คือถ้าคุณไม่ได้รวมคำสั่งพิมพ์ใน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 และโค้ดต่อไปนี้จะเป็นสิ่งที่คุณต้องอ่าน 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วงและมันก็ยังคงพิมพ์คอลัมน์สุดท้ายเท่านั้นซึ่งไม่ควรเกิดขึ้น แต่แจ้งให้เราทราบหากการสันนิษฐานของฉันผิด รหัสที่โพสต์ของคุณมีข้อผิดพลาดในการเยื้องจำนวนมากดังนั้นจึงเป็นเรื่องยากที่จะทราบว่าควรจะอยู่ที่ไหน หวังว่านี่จะเป็นประโยชน์!


1
เป็นไปได้ไหมที่จะลบหมายเลขดัชนีออกจากแบบสอบถาม @Ryan Saxe
Malachi Bazar

ใช่แค่วนซ้ำในวงวน
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'])

ด้วยไฟล์ที่ชอบ

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=" ")


30

ใช้แพนด้า :

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

ป.ล. ฉันแค่รวบรวมสิ่งที่คนอื่นพูดด้วยวิธีง่าย ๆ คำตอบที่เกิดขึ้นจริงที่นำมาจากที่นี่และที่นี่


1
ฉันคิดว่า Pandas เป็นทางออกที่ดีที่สุด ฉันใช้หมีแพนด้าบ่อยครั้งและชอบห้องสมุดจริงๆ แต่คำถามนี้อ้างอิงโมดูล CSV โดยเฉพาะ
frankV

1
@frankV ดีชื่อแท็กและย่อหน้าแรกไม่ห้ามแพนด้าในทางใดทางหนึ่ง AFAI สามารถดูได้ ที่จริงแล้วฉันก็แค่หวังว่าจะเพิ่มคำตอบที่ง่ายกว่าสำหรับคนที่ทำไว้แล้วที่นี่ (คำตอบอื่น ๆ ก็ใช้แพนด้าเช่นกัน)
VasiliNovikov

18

ด้วยนุ่นคุณสามารถใช้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

16

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' หรือไม่
114

6

บริบท: สำหรับงานประเภทนี้คุณควรใช้ห้องสมุดหลามหลามที่น่าตื่นตาตื่นใจ ที่จะช่วยให้คุณประหยัดงานและความยุ่งยากในการทำสิ่งต่างๆด้วยตนเองด้วยโมดูล csv มาตรฐาน AFAIK คนเดียวที่ยังคงใช้โมดูล csv คือผู้ที่ยังไม่ได้ค้นพบเครื่องมือที่ดีกว่าสำหรับการทำงานกับข้อมูลแบบตาราง (pandas, petl ฯลฯ ) ซึ่งใช้ได้ แต่ถ้าคุณวางแผนที่จะทำงานกับข้อมูลจำนวนมากใน อาชีพของคุณจากแหล่งข้อมูลแปลก ๆ การเรียนรู้อะไรบางอย่างเช่น Petl เป็นหนึ่งในการลงทุนที่ดีที่สุดที่คุณสามารถทำได้ ในการเริ่มต้นควรใช้เวลา 30 นาทีหลังจากที่คุณติดตั้ง pip ติดตั้ง 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')

4

ฉันคิดว่ามีวิธีที่ง่ายกว่า

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 |

ถ้ามันใช้งานได้โปรดโหวตให้คนอื่นรู้ :)
Nuriddin Kudratov


1

ด้วยวิธีที่คุณสามารถจัดทำดัชนีและเซตดาต้าดาต้าของแพนด้าเป็นวิธีที่ง่ายมากในการแยกคอลัมน์เดียวจากไฟล์ csv ลงในตัวแปรคือ:

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

สิ่งที่ควรพิจารณา:

ข้อมูลข้างต้นจะผลิตแพนด้าและไม่ได้Series dataframeข้อเสนอแนะจาก ayhan พร้อมusecolsจะเร็วขึ้นหากความเร็วเป็นปัญหา การทดสอบสองแนวทางที่แตกต่างกันโดยใช้%timeitไฟล์ csv ขนาด 2122 KB ให้ผลตอบแทน22.8 msสำหรับแนวทาง usecols และ53 msสำหรับแนวทางที่แนะนำของฉัน

และอย่าลืม import pandas as pd


0

หากคุณต้องการประมวลผลคอลัมน์แยกกันฉันต้องการสร้างคอลัมน์ด้วยzip(*iterable)รูปแบบ (มีประสิทธิภาพ "คลายซิป") ดังนั้นสำหรับตัวอย่างของคุณ:

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

-1

หากต้องการดึงชื่อคอลัมน์แทนที่จะใช้readlines ()ควรใช้readline ()เพื่อหลีกเลี่ยงการวนซ้ำ & อ่านไฟล์ที่สมบูรณ์และเก็บไว้ในอาร์เรย์

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

    # get number of columns

    line = csvfile.readline()

    first_item = line.split(',')
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.