Pythonはcsvをリストにインポートします


192

約2000レコードのCSVファイルがあります。

各レコードには文字列とそのカテゴリがあります。

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

回答:


304

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

古い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
なぜ「r」の代わりに「rb」を使用するのですか?
imrek

5
@DrunkenMaster。bファイルをテキストモードではなくバイナリモードで開きます。一部のシステムでは、テキストモードは\n、読み取りまたは書き込み時にプラットフォーム固有の新しい行に変換されることを意味します。docsを参照してください
Maciej Gol

7
これはPython 3.xでは機能しません: "csv.Error:イテレータはバイトではなく文字列を返す必要があります(テキストモードでファイルを開きましたか?)" Python 3.xで機能する回答については、以下を参照してください
Gilbert

2
数秒のデバッグ時間を節約するには、おそらく「Python 2.xバージョン」のような最初のソリューションのメモを追加する必要があります
パラダイト

最初のソリューションを使用する方法はありますが、csvファイルの一部の列のみを使用していますか?
シグル2017年

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

43

Pandasは、データの扱いにかなり長けています。これを使用する方法の一例を次に示します。

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

1つの大きな利点は、パンダがヘッダー行を自動的に処理することです。

Seabornについて聞いたことがない場合は、ぜひご覧ください。

参照:PythonでCSVファイルを読み書きするにはどうすればよいですか?

パンダ#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

辞書の内容は

[{'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()。3番目の例は私を混乱させます。まず、変数の名前がtuplesであるため、タプルのリストであることを意味しますが、実際にはリストのリストです。第二に、私が知る限り、式全体をで置き換えることができるからdf.to_list()です。ここで、2番目の例が本当に関連しているかどうかもわかりません。
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())リスト内包表記を使用する理由 また、2番目の列の各要素の先頭にある空白に注意してください。
AMC

5

あなたは必ず、あなたの入力にはカンマは、カテゴリを分離する以外にはありませんしている場合は、あなたができる行毎にファイルを読み込む分割,し、に結果をプッシュしますList

あなたが使用して検討するかもしれないので、それは、CSVファイルを見ているように見える、と述べたモジュールをそれのために


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

1
この投稿に少し説明を追加してもらえますか?コードは(たまに)良いだけですが、コードと説明は(ほとんどの場合)優れています
Barranka

3
私はBarrankaのコメントが1年以上前のものであることを知っていますが、これにつまずいてそれを理解できない人のために:text.splitlines()のlineの場合:個々の行を一時変数 "line"に入れます。line.split( "、")は、コンマで分割される文字列のリストを作成します。tuple(〜)はそのリストをタプルに入れ、append(〜)はそれを結果に追加します。ループの後、結果はタプルのリストであり、各タプルは1行であり、各タプル要素はcsvファイル内の要素です。
Louis

@Louisが言ったことに加えて、を使用する必要はありません。.read().splitlines()ファイルの各行を直接繰り返すことができます。for line in in_file: res.append(tuple(line.rstrip().split(",")))また、使用.split(',')すると、2列目のすべての要素が余分な空白で始まることになります。
AMC

上記で共有したばかりのコードの補足:line.rstrip()-> line.rstrip('\n')
AMC

3

コメントですでに述べたように、あなたは使うことができます csv、Pythonでライブラリを。csvはカンマで区切られた値を意味します。これはまさにあなたのケースのように見えます:ラベルとコンマで区切られた値

カテゴリーと値のタイプなので、タプルのリストの代わりに辞書タイプを使用したいと思います。

とにかく以下のコードで私は両方の方法を示します: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)

ファイルを処理するためにコンテキストマネージャーを使用しないのはなぜですか?なぜ2つの異なる変数の命名規則が混在しているのですか?ではない(row[0], row[1])弱い/より多くのエラーが発生しやすいだけで使用するよりもtuple(row)
AMC

tuple(row)を実行するとエラーが発生しにくいと思うのはなぜですか?公式のPython命名規則をリンクしてください。私が知る限り、try -exceptはファイルを処理するための良い方法です。コンテキストハンドラーで何を意味しますか?
Francesco Boi

なぜタプル(行)を実行するとエラーが発生しにくいと思いますか?手動ですべてのインデックスを書き出す必要がないためです。間違えたり、要素の数が変わったりした場合は、戻ってコードを変更する必要があります。try-exceptは問題なく、コンテキストマネージャはwithステートメントです。あなたのような、被写体に資源の多くを見つけることができ、この 1。
AMC

コンテキストマネージャーが昔ながらのtry-exceptブロックよりも優れていることはわかりません。他の肯定的な側面は、uが入力するコードが少ないことです。残りの要素の数(私はuは列の数を意味すると思います)が変更された場合、それは望ましい値のみを抽出し、他はすべてのExcelを抽出するため、私にとってはより良い方法です。特定の要件がないとどちらが良いかは言えないので、どちらが良いかを議論するのは時間の無駄です。この場合、両方が有効です
Francesco Boi

コンテキストマネージャーが昔ながらのtry-exceptブロックよりも優れていることはわかりません。以前のコメントを参照してください。コンテキストマネージャ try-exceptを置き換えません
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による回答は、Pythonに付属のcsvパーサーを使用してこの操作を実行する方法を示しています。このパーサーには、必要なロジックがすべて含まれていると考えられます。
ハンターマクミレン

1

残念ながら、既存の回答のどれも特に満足できるものはありません。

以下は、csvモジュールを使用した簡単で完全なPython 3ソリューションです。

import csv

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

print(rows)

skipinitialspace=True引数に注意してください。残念ながら、OPのCSVには各カンマの後に空白が含まれているため、これが必要です。

出力:

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

注意してください、それは配列ではなくリストです!ファイルオブジェクトを適切に処理するためにコンテキストマネージャーを使用しないのはなぜですか?このソリューションでは、各行の2番目のアイテムに余分な空白が残され、データにカンマが含まれていると失敗することに注意してください。
AMC

-1

次は、csvモジュールを使用するコードの一部ですが、csvテーブルのヘッダーである最初の行を使用して、dictsのリストにfile.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.