Listelenecek Python içe aktarma CSV


193

Yaklaşık 2000 kayıtları olan bir CSV dosyam var.

Her kaydın bir dizesi ve kategorisi vardır:

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

Bu dosyayı şöyle görünen bir listeye okumalıyım:

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

Bu CSV'yi Python kullanarak ihtiyacım olan listeye nasıl aktarabilirim?


2
Ardından csvmodülü kullanın : docs.python.org/2/library/csv.html
furas

4
Sorunuza uygun bir cevap varsa, lütfen kabul edin.
Maciej Gol

Yanıtlar:


307

Csv modülünü kullanarak :

import csv

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

print(data)

Çıktı:

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

Tuples'e ihtiyacınız varsa:

import csv

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

print(data)

Çıktı:

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

Eski Python 2 yanıtı, ayrıca csvmodülü kullanarak :

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
Neden 'r' yerine 'rb' kullanıyorsunuz?
imrek

5
@DrunkenMaster, bdosyanın metin modunun aksine ikili modda açılmasına neden olur. Bazı sistemlerde metin modu \n, okuma veya yazma sırasında platforma özgü yeni satıra dönüştürüleceği anlamına gelir . Dokümanlara bakın .
Maciej Gol

7
Bu Python 3.x'de çalışmaz: "csv.Error: yineleyici bayt değil, dizeleri döndürmelidir (dosyayı metin modunda açtınız mı?)" Python 3.x'te çalışan yanıt için aşağıya bakın
Gilbert

2
hata ayıklama birkaç saniye kaydetmek için, muhtemelen "Python 2.x sürümü" gibi ilk çözüm için bir not eklemeniz gerekir
paradite

1. çözümünüzü ancak csv dosyasından yalnızca bazı sütunlarla nasıl kullanabilirsiniz?
Sigur

54

Python 3 için güncellendi :

import csv

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

print(your_list)

Çıktı:

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

belirtme 'r' varsayılan moddur, dolayısıyla belirtmek gereksizdir. Dokümanlar ayrıca csvfile bir dosya nesnesiyse, newline = '' ile açılmalıdır.
AMC

44

Pandalar verilerle uğraşmada oldukça iyidir. İşte nasıl kullanılacağı ile ilgili bir örnek:

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

Bir büyük avantaj pandaların başlık satırlarıyla otomatik olarak ilgilenmesidir.

Eğer duymamış Eğer Seaborn , ben ona bir göz sahip önerilir.

Ayrıca bkz: Python ile CSV dosyalarını nasıl okurum ve yazarım?

Pandalar # 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 içeriği:

     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 içeriği

[{'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}]

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

İçeriği 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))bunun yerine yazılabilir . Pandalar belgelerinin .valueslehine kullanımını caydırdığını unutmayın .to_numpy(). Üçüncü örnek bana kafa karıştırıyor. Birincisi, değişken isimlendirildiğinden tuples, bunun bir grup listesi olduğunu ima ederken, aslında bir liste listesidir. İkincisi, çünkü söyleyebildiğim kadarıyla tüm ifadenin yerini alabilir df.to_list(). İkinci örneğin burada gerçekten alakalı olup olmadığını da bilmiyorum.
AMC

9

Python3 için güncelleme:

import csv
from pprint import pprint

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

pprint(res)

Çıktı:

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

Csvfile bir dosya nesnesiyse, ile açılması gerekir newline=''.
csv modülü


Neden list(map())bir liste kavrayışı kullanılır? Ayrıca, ikinci sütunun her öğesinin başındaki boşluklara dikkat edin.
AMC


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

1
Lütfen bu gönderiye biraz açıklama ekleyebilir misiniz? Kod sadece (bazen) iyidir, ancak kod ve açıklama (çoğu zaman) daha iyidir
Barranka

3
Barranka'nın yorumunun bir yıldan daha eski olduğunu biliyorum, ancak bunun üzerine tökezleyen ve anlayamayan herkes için : line in text.splitlines (): her satırı ayrı ayrı "line" değişkenine koyar. line.split (",") virgülle ayrılmış dizelerin bir listesini oluşturur. tuple (~) bu listeyi bir tuple içine yerleştirir ve (~) eki listeye sonuca ekler. Döngüden sonra, sonuç her tuple bir çizgi ve her tuple elemanı csv dosyasındaki bir elemanla birlikte bir tuples listesidir.
Louis

@Louis'in söylediklerine ek olarak, kullanmaya gerek yoktur .read().splitlines(), doğrudan dosyanın her satırı üzerinde yineleme yapabilirsiniz: for line in in_file: res.append(tuple(line.rstrip().split(",")))Ayrıca, .split(',')ikinci sütunun her öğesinin ekstra boşlukla başlayacağı anlamına gelir.
AMC

Yukarıda paylaştığım koda ek: line.rstrip()-> line.rstrip('\n').
AMC

3

Zaten yorumlarda belirtildiği gibi csvkütüphaneyi python'da kullanabilirsiniz. csv tam olarak sizin durumunuz gibi görünen virgülle ayrılmış değerler anlamına gelir: bir etiket ve virgülle ayrılmış bir değer.

Bir kategori ve değer türü olmak yerine tuples listesi yerine sözlük türü kullanmak istiyorum.

Her neyse aşağıdaki kodda her iki yolu da gösteriyorum: dsözlük ve ltuples listesi.

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)

Dosyayı işlemek için neden bağlam yöneticisi kullanmıyorsunuz? Neden iki farklı değişken adlandırma kuralını karıştırıyorsunuz? Is not (row[0], row[1])zayıf / fazla hataya eğilimli sadece kullanmaktan daha tuple(row)?
AMC

Neden tuple (satır) yapmanın daha az hataya yatkın olduğunu düşünüyorsunuz? Lütfen resmi bir python adlandırma kuralı bağlayın. Bildiğim kadarıyla try -except dosyaları işlemek için iyi bir yoldur: u bağlam işleyicisi ile ne demek istiyorsun?
Francesco Boi

Neden tuple (satır) yapmanın daha az hataya eğilimli olduğunu düşünüyorsunuz? Çünkü her bir dizini manuel olarak yazmanızı gerektirmez. Bir hata yaparsanız veya öğe sayısı değişirse, geri dönüp kodunuzu değiştirmeniz gerekir. Try-haricinde sorun yok, bağlam yöneticileri with ifadesi. Aşağıdaki gibi, konuyla ilgili birçok kaynak bulabilirsiniz bu one.
AMC

Bağlam yöneticisinin ol 'iyi deneme-hariç blokundan nasıl daha iyi olacağını görmüyorum. Diğeri için olumlu yönü u daha az kod yazmasıdır; geri kalanı için eleman sayısı (sanırım u sütun sayısı anlamına gelir) benimkini daha iyi çünkü sadece istenen değerleri ayıklarken diğer tüm excel ayıklanıyor. Herhangi bir özel gereksinim olmadan hangisinin daha iyi olduğunu söyleyemezsiniz, bu da hangisinin daha iyi olduğunu tartışmak için zaman kaybıdır: bu durumda her ikisi de geçerlidir
Francesco Boi

Bağlam yöneticisinin ol 'iyi deneme-hariç blokundan nasıl daha iyi olacağını göremiyorum. Lütfen önceki yorumuma bakın, içerik yöneticisi try-hariç yerine geçmez .
AMC

2

Basit bir döngü yeterlidir:

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
Girişlerin bazılarında virgül varsa ne olur?
Tony Ennis

@TonyEnnis O zaman daha gelişmiş bir işlem döngüsü kullanmanız gerekir. Yukarıdaki Maciej'in cevabı, bu işlemi gerçekleştirmek için Python ile birlikte gelen csv ayrıştırıcısının nasıl kullanılacağını gösterir. Bu ayrıştırıcı büyük olasılıkla ihtiyacınız olan tüm mantığa sahiptir.
Hunter McMillen

1

Ne yazık ki mevcut cevapların hiçbirini tatmin edici bulmuyorum.

İşte csv modülünü kullanarak basit ve eksiksiz bir Python 3 çözümü .

import csv

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

print(rows)

Argümana dikkat edin skipinitialspace=True. Maalesef, OP'nin CSV'si her virgülden sonra boşluk içerdiğinden bu gereklidir.

Çıktı:

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

0

Gereksinimlerinizi biraz genişletmek ve satırların sırasını önemsemediğinizi ve bunları kategoriler altında gruplandırmak istediğinizi varsayarsak, aşağıdaki çözüm sizin için işe yarayabilir:

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

Bu şekilde, kategorideki anahtarın altındaki sözlükte bulunan tüm ilgili satırları elde edersiniz.


0

Python 3.x'te bir CSV'yi çok boyutlu bir diziye içe aktarmanın en kolay yolu ve hiçbir şey içe aktarmadan sadece 4 kod satırı!

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

Dikkatli olun, bu bir liste, bir dizi değil! Dosya nesnesini düzgün işlemek için neden bir bağlam yöneticisi kullanmıyorsunuz? Bu çözümün, her satırdaki ikinci öğeye fazladan boşluk bıraktığını ve verilerin herhangi bir virgül içeriyorsa başarısız olacağını unutmayın.
AMC

-1

Sonraki, csv modülünü kullanan ancak csv tablosunun üstbilgisi olan ilk satırı kullanan bir dicts dosyasına file.csv içeriğini ayıklayan bir kod parçasıdır.

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
Neden sadece kullanmıyorsunuz csv.DictReader?
AMC
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.