Python นำเข้า csv ไปที่รายการ


193

ฉันมีไฟล์ CSV ที่มีระเบียนประมาณ 2000 รายการ

แต่ละระเบียนมีสตริงและหมวดหมู่:

This is the first line,Line1
This is the second line,Line2
This is the third line,Line3

ฉันต้องการอ่านไฟล์นี้ลงในรายการที่มีลักษณะดังนี้:

data = [('This is the first line', 'Line1'),
        ('This is the second line', 'Line2'),
        ('This is the third line', 'Line3')]

จะนำเข้า CSV นี้ไปยังรายการที่ฉันต้องการโดยใช้ Python ได้อย่างไร


2
จากนั้นใช้csvโมดูล: docs.python.org/2/library/csv.html
furas

4
หากมีคำตอบที่ตรงกับคำถามของคุณโปรดยอมรับมัน
Maciej Gol

คำตอบ:


307

การใช้โมดูล csv :

import csv

with open('file.csv', newline='') as f:
    reader = csv.reader(f)
    data = list(reader)

print(data)

เอาท์พุท:

[['This is the first line', 'Line1'], ['This is the second line', 'Line2'], ['This is the third line', 'Line3']]

หากคุณต้องการสิ่งอันดับ:

import csv

with open('file.csv', newline='') as f:
    reader = csv.reader(f)
    data = [tuple(row) for row in reader]

print(data)

เอาท์พุท:

[('This is the first line', 'Line1'), ('This is the second line', 'Line2'), ('This is the third line', 'Line3')]

Old Python 2 คำตอบใช้csvโมดูล:

import csv
with open('file.csv', 'rb') as f:
    reader = csv.reader(f)
    your_list = list(reader)

print your_list
# [['This is the first line', 'Line1'],
#  ['This is the second line', 'Line2'],
#  ['This is the third line', 'Line3']]

4
ทำไมคุณใช้ 'rb' แทน 'r'
imrek

5
@DrunkenMaster bทำให้ไฟล์ถูกเปิดในโหมดไบนารีตรงข้ามกับโหมดข้อความ ในบางระบบข้อความโหมดหมายความว่า\nจะถูกแปลงเป็นบรรทัดใหม่เฉพาะแพลตฟอร์มเมื่ออ่านหรือเขียน ดูเอกสาร
Maciej Gol

7
สิ่งนี้ใช้ไม่ได้ใน Python 3.x: "csv.Error: iterator ควรส่งคืนสตริงไม่ใช่ไบต์ (คุณเปิดไฟล์ในโหมดข้อความหรือไม่)" ดูคำตอบที่ใช้งานได้ใน Python 3.x ด้านล่าง
Gilbert

2
เพื่อประหยัดเวลาไม่กี่วินาทีของการแก้จุดบกพร่องเวลาที่คุณอาจจะเพิ่มบันทึกสำหรับการแก้ปัญหาก่อนเช่น "งูใหญ่รุ่น 2.x"
paradite

วิธีใช้โซลูชันที่ 1 ของคุณ แต่มีเพียงบางคอลัมน์จากไฟล์ csv เท่านั้น
Sigur

54

อัปเดตสำหรับPython 3 :

import csv

with open('file.csv', newline='') as f:
    reader = csv.reader(f)
    your_list = list(reader)

print(your_list)

เอาท์พุท:

[['This is the first line', 'Line1'], ['This is the second line', 'Line2'], ['This is the third line', 'Line3']]

การระบุ'r'เป็นโหมดเริ่มต้นดังนั้นการระบุว่าไม่จำเป็น เอกสารยังกล่าวถึงหาก csvfile เป็นวัตถุไฟล์ควรเปิดด้วย newline = ''
AMC

44

หมีแพนด้าค่อนข้างดีในการจัดการกับข้อมูล นี่คือตัวอย่างหนึ่งวิธีการใช้งาน:

import pandas as pd

# Read the CSV into a pandas data frame (df)
#   With a df you can do many things
#   most important: visualize data with Seaborn
df = pd.read_csv('filename.csv', delimiter=',')

# Or export it in many ways, e.g. a list of tuples
tuples = [tuple(x) for x in df.values]

# or export it as a list of dicts
dicts = df.to_dict().values()

ข้อได้เปรียบที่สำคัญข้อหนึ่งคือแพนด้าจะจัดการกับแถวส่วนหัวโดยอัตโนมัติ

หากคุณไม่เคยได้ยินเกี่ยวกับทะเลฉันแนะนำให้ลองดู

ดูเพิ่มเติม: ฉันจะอ่านและเขียนไฟล์ CSV ด้วย Python ได้อย่างไร

นุ่น # 2

import pandas as pd

# Get data - reading the CSV file
import mpu.pd
df = mpu.pd.example_df()

# Convert
dicts = df.to_dict('records')

เนื้อหาของ df คือ:

     country   population population_time    EUR
0    Germany   82521653.0      2016-12-01   True
1     France   66991000.0      2017-01-01   True
2  Indonesia  255461700.0      2017-01-01  False
3    Ireland    4761865.0             NaT   True
4      Spain   46549045.0      2017-06-01   True
5    Vatican          NaN             NaT   True

เนื้อหาของ dicts คือ

[{'country': 'Germany', 'population': 82521653.0, 'population_time': Timestamp('2016-12-01 00:00:00'), 'EUR': True},
 {'country': 'France', 'population': 66991000.0, 'population_time': Timestamp('2017-01-01 00:00:00'), 'EUR': True},
 {'country': 'Indonesia', 'population': 255461700.0, 'population_time': Timestamp('2017-01-01 00:00:00'), 'EUR': False},
 {'country': 'Ireland', 'population': 4761865.0, 'population_time': NaT, 'EUR': True},
 {'country': 'Spain', 'population': 46549045.0, 'population_time': Timestamp('2017-06-01 00:00:00'), 'EUR': True},
 {'country': 'Vatican', 'population': nan, 'population_time': NaT, 'EUR': True}]

นุ่น # 3

import pandas as pd

# Get data - reading the CSV file
import mpu.pd
df = mpu.pd.example_df()

# Convert
lists = [[row[col] for col in df.columns] for row in df.to_dict('records')]

เนื้อหาของlistsคือ:

[['Germany', 82521653.0, Timestamp('2016-12-01 00:00:00'), True],
 ['France', 66991000.0, Timestamp('2017-01-01 00:00:00'), True],
 ['Indonesia', 255461700.0, Timestamp('2017-01-01 00:00:00'), False],
 ['Ireland', 4761865.0, NaT, True],
 ['Spain', 46549045.0, Timestamp('2017-06-01 00:00:00'), True],
 ['Vatican', nan, NaT, True]]

tuples = [tuple(x) for x in df.values]สามารถเขียนtuples = list(df.itertuples(index=False))แทน ทำทราบว่าเอกสารนุ่นกีดกันการใช้ในความโปรดปรานของ.values .to_numpy()ตัวอย่างที่สามทำให้ฉันสับสน ครั้งแรกเนื่องจากชื่อตัวแปรtuplesซึ่งจะบอกเป็นนัยว่าเป็นรายการของ tuples ในขณะที่มันเป็นรายการของรายการ df.to_list()ประการที่สองเนื่องจากเท่าที่ผมสามารถบอกได้ว่าการแสดงออกทั้งสามารถถูกแทนที่ด้วย ฉันไม่รู้ด้วยซ้ำว่าตัวอย่างที่สองเกี่ยวข้องกับที่นี่จริงหรือไม่
AMC

9

อัพเดทสำหรับ Python3:

import csv
from pprint import pprint

with open('text.csv', newline='') as file:
    reader = csv.reader(file)
    res = list(map(tuple, reader))

pprint(res)

เอาท์พุท:

[('This is the first line', ' Line1'),
 ('This is the second line', ' Line2'),
 ('This is the third line', ' Line3')]

หาก csvfile newline=''เป็นวัตถุไฟล์ก็ควรจะเปิด
โมดูล csv


เหตุใดจึงต้องใช้list(map())มากกว่าความเข้าใจในรายการ? นอกจากนี้ให้สังเกตช่องว่างในตอนต้นของแต่ละองค์ประกอบของคอลัมน์ที่สอง
AMC

5

ถ้าคุณแน่ใจว่ามีเครื่องหมายจุลภาคในการป้อนข้อมูลของคุณไม่ได้อื่น ๆ กว่าจะแยกหมวดหมู่ที่คุณสามารถอ่านบรรทัดไฟล์โดยสายและแยกบน,แล้วผลักดันผลให้List

ที่กล่าวมาดูเหมือนว่าคุณกำลังดูไฟล์ CSV ดังนั้นคุณอาจพิจารณาใช้โมดูลสำหรับมัน


4
result = []
for line in text.splitlines():
    result.append(tuple(line.split(",")))

1
คุณช่วยเพิ่มคำอธิบายเล็กน้อยในโพสต์นี้ได้ไหม รหัสเท่านั้นคือ (บางครั้ง) ดี แต่รหัสและคำอธิบายดีกว่า (มากที่สุด)
Barranka

3
ฉันรู้ว่าความคิดเห็นของ Barranka มีอายุเกินหนึ่งปี แต่สำหรับใครก็ตามที่สะดุดกับสิ่งนี้และไม่สามารถหาคำตอบได้: สำหรับบรรทัดใน text.splitlines ():ใส่แต่ละบรรทัดในตัวแปร temp "line" line.split (",")สร้างรายการของสตริงที่แบ่งในเครื่องหมายจุลภาค tuple (~)ใส่รายการนั้นใน tuple และผนวก (~)เพิ่มเข้าไปในผลลัพธ์ หลังจากวนลูปผลลัพธ์คือรายการของ tuples โดยที่แต่ละ tuple เป็นบรรทัดและแต่ละองค์ประกอบ tuple เป็นองค์ประกอบในไฟล์ csv
Louis

นอกจากสิ่งที่ @Louis พูดแล้วไม่จำเป็นต้องใช้.read().splitlines()คุณสามารถวนซ้ำในแต่ละบรรทัดของไฟล์โดยตรง: for line in in_file: res.append(tuple(line.rstrip().split(",")))นอกจากนี้โปรดทราบว่าการใช้.split(',')หมายความว่าทุกองค์ประกอบของคอลัมน์ที่สองจะขึ้นต้นด้วยช่องว่างเพิ่มเติม
AMC

ภาคผนวกรหัสฉันเพียงแค่ร่วมกันดังกล่าวข้างต้น: ->line.rstrip() line.rstrip('\n')
บบส

3

ดังที่ได้กล่าวไปแล้วในความคิดเห็นที่คุณสามารถใช้ csvห้องสมุดในหลาม csv หมายถึงค่าที่คั่นด้วยเครื่องหมายจุลภาคซึ่งดูเหมือนว่ากรณีของคุณ: ป้ายกำกับและค่าคั่นด้วยเครื่องหมายจุลภาค

เป็นประเภทและประเภทค่าฉันค่อนข้างจะใช้ประเภทพจนานุกรมแทนรายการของ tuples

อย่างไรก็ตามในรหัสด้านล่างฉันแสดงทั้งสองวิธี: dเป็นพจนานุกรมและlเป็นรายการของสิ่งอันดับ

import csv

file_name = "test.txt"
try:
    csvfile = open(file_name, 'rt')
except:
    print("File not found")
csvReader = csv.reader(csvfile, delimiter=",")
d = dict()
l =  list()
for row in csvReader:
    d[row[1]] = row[0]
    l.append((row[0], row[1]))
print(d)
print(l)

ทำไมไม่ใช้ตัวจัดการบริบทเพื่อจัดการไฟล์? เหตุใดคุณจึงผสมแบบแผนการตั้งชื่อตัวแปรที่แตกต่างกันสองแบบ ไม่ได้(row[0], row[1])ปรับตัวลดลง / อื่น ๆ ผิดพลาดได้ง่ายกว่าเพียงแค่ใช้tuple(row)?
AMC

ทำไมคุณถึงคิดว่าการทำ tuple (แถว) มีข้อผิดพลาดน้อยกว่านั้นคืออะไรรูปแบบการตั้งชื่อตัวแปรที่คุณอ้างถึงคืออะไร โปรดเชื่อมโยงแบบแผนการตั้งชื่อของไพ ธ อนอย่างเป็นทางการ เท่าที่ฉันทราบลอง -Except เป็นวิธีที่ดีในการจัดการไฟล์: u หมายถึงอะไรโดยบริบทจัดการ?
Francesco Boi

ทำไมคุณคิดว่าการทำ tuple (แถว) มีข้อผิดพลาดน้อยลง? เพราะมันไม่ต้องการให้คุณเขียนทุก ๆ ดัชนีด้วยตนเอง หากคุณทำผิดพลาดหรือจำนวนองค์ประกอบเปลี่ยนแปลงคุณต้องย้อนกลับและเปลี่ยนรหัสของคุณ การลองยกเว้นเป็นเรื่องปกติผู้จัดการบริบทเป็นคำสั่ง with คุณสามารถค้นหาความอุดมสมบูรณ์ของทรัพยากรในเรื่องเช่นนี้อย่างใดอย่างหนึ่ง
AMC

ฉันไม่เห็นว่าตัวจัดการบริบทจะดีกว่าตัวบล็อกลองดียกเว้น ol อย่างไร สำหรับด้านอื่น ๆ ข้อดีคือคุณพิมพ์รหัสน้อยลง สำหรับส่วนที่เหลือถ้าจำนวนองค์ประกอบ (ฉันเดาว่าคุณหมายถึงจำนวนคอลัมน์) การเปลี่ยนแปลงของฉันดีกว่าเพราะมันจะดึงเฉพาะค่าที่ต้องการในขณะที่อีกองค์ประกอบหนึ่งจะสกัด excel ทั้งหมด หากไม่มีข้อกำหนดเฉพาะคุณไม่สามารถบอกได้ว่าอะไรดีกว่ากันดังนั้นจึงเป็นการเสียเวลาที่จะเถียงกันซึ่งดีกว่า: ในกรณีนี้ทั้งคู่ใช้ได้
Francesco Boi

ฉันไม่เห็นว่าตัวจัดการบริบทจะดีกว่าตัวบล็อกลองดียกเว้น ol อย่างไร โปรดดูความคิดเห็นก่อนหน้าของฉันผู้จัดการบริบทจะไม่แทนที่การลองยกเว้น
AMC

2

การวนรอบง่ายจะพอเพียง:

lines = []
with open('test.txt', 'r') as f:
    for line in f.readlines():
        l,name = line.strip().split(',')
        lines.append((l,name))

print lines

1
เกิดอะไรขึ้นถ้าบางรายการมีจุลภาคในพวกเขา?
Tony Ennis

@TonyEnnis จากนั้นคุณจะต้องใช้ลูปการประมวลผลขั้นสูงเพิ่มเติม คำตอบโดย Maciej ด้านบนแสดงวิธีใช้ csv parser ที่มาพร้อมกับ Python เพื่อดำเนินการนี้ โปรแกรมแยกวิเคราะห์นี้น่าจะมีเหตุผลทั้งหมดที่คุณต้องการ
Hunter McMillen

1

น่าเสียดายที่ฉันไม่พบคำตอบที่มีอยู่โดยเฉพาะอย่างยิ่งที่น่าพอใจ

นี่คือโซลูชัน Python 3 ที่เรียบง่ายและสมบูรณ์โดยใช้โมดูลcsv

import csv

with open('../resources/temp_in.csv', newline='') as f:
    reader = csv.reader(f, skipinitialspace=True)
    rows = list(reader)

print(rows)

สังเกตการskipinitialspace=Trueโต้แย้ง นี่เป็นสิ่งจำเป็นเนื่องจาก CSV ของ OP มีช่องว่างหลังจากแต่ละเครื่องหมายจุลภาค

เอาท์พุท:

[['This is the first line', 'Line1'], ['This is the second line', 'Line2'], ['This is the third line', 'Line3']]

0

ขยายความต้องการของคุณออกไปเล็กน้อยและสมมติว่าคุณไม่สนใจลำดับของบรรทัดและต้องการให้จัดกลุ่มตามหมวดหมู่โซลูชันต่อไปนี้อาจทำงานให้คุณ:

>>> fname = "lines.txt"
>>> from collections import defaultdict
>>> dct = defaultdict(list)
>>> with open(fname) as f:
...     for line in f:
...         text, cat = line.rstrip("\n").split(",", 1)
...         dct[cat].append(text)
...
>>> dct
defaultdict(<type 'list'>, {' CatA': ['This is the first line', 'This is the another line'], ' CatC': ['This is the third line'], ' CatB': ['This is the second line', 'This is the last line']})

วิธีนี้ทำให้คุณได้รับบรรทัดที่เกี่ยวข้องทั้งหมดในพจนานุกรมภายใต้คีย์เป็นหมวดหมู่


0

นี่เป็นวิธีที่ง่ายที่สุดใน Python 3.x เพื่อนำเข้า CSV ไปยังอาร์เรย์หลายมิติและมีโค้ดเพียง 4 บรรทัดโดยไม่ต้องนำเข้าอะไร!

#pull a CSV into a multidimensional array in 4 lines!

L=[]                            #Create an empty list for the main array
for line in open('log.txt'):    #Open the file and read all the lines
    x=line.rstrip()             #Strip the \n from each line
    L.append(x.split(','))      #Split each line into a list and add it to the
                                #Multidimensional array
print(L)

ระวังเป็นรายการไม่ใช่อาร์เรย์! ทำไมไม่ใช้ตัวจัดการบริบทเพื่อจัดการวัตถุไฟล์อย่างถูกต้อง? โปรดทราบว่าวิธีนี้จะทำให้มีพื้นที่ว่างเหลืออยู่ในรายการที่สองในแต่ละแถวและจะล้มเหลวหากข้อมูลใด ๆ มีเครื่องหมายจุลภาค
AMC

-1

ถัดไปเป็นชิ้นส่วนของรหัสที่ใช้โมดูล csv แต่แยกเนื้อหา file.csv ไปยังรายการของ dicts โดยใช้บรรทัดแรกซึ่งเป็นส่วนหัวของตาราง csv

import csv
def csv2dicts(filename):
  with open(filename, 'rb') as f:
    reader = csv.reader(f)
    lines = list(reader)
    if len(lines) < 2: return None
    names = lines[0]
    if len(names) < 1: return None
    dicts = []
    for values in lines[1:]:
      if len(values) != len(names): return None
      d = {}
      for i,_ in enumerate(names):
        d[names[i]] = values[i]
      dicts.append(d)
    return dicts
  return None

if __name__ == '__main__':
  your_list = csv2dicts('file.csv')
  print your_list

1
ทำไมไม่ใช้เพียงcsv.DictReader?
AMC
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.