CSVデータを処理するときにデータの最初の行を無視する方法は?


113

PythonにCSVデータの列から最小数を出力するように依頼していますが、一番上の行は列番号であり、Pythonが一番上の行を考慮に入れたくありません。Pythonが最初の行を無視するようにするにはどうすればよいですか?

これはこれまでのコードです:

import csv

with open('all16.csv', 'rb') as inf:
    incsv = csv.reader(inf)
    column = 1                
    datatype = float          
    data = (datatype(column) for row in incsv)   
    least_value = min(data)

print least_value

コードを与えるだけでなく、何をしているのか説明してもらえますか?私はPythonに非常に慣れていないので、すべてを確実に理解したいと思います。


5
1.0ファイル内の各行のを返すジェネレータを作成し、最小値を取ることを知っています1.0か?
Wooble

@Wooble技術的には、の大きなジェネレーターです1.0。:)
Dougal

@Woobleグッドキャッチ-... ... datatype(row[column]OPが達成しようとしていることだと思います
Jon Clements

誰かにそのコードを書いてもらえなかったので、ありがとうございます!

回答:


106

csvモジュールのSnifferクラスのインスタンスを使用してCSVファイルの形式を推定し、組み込みnext()関数と共にヘッダー行が存在するかどうかを検出して、必要な場合にのみ最初の行をスキップできます。

import csv

with open('all16.csv', 'r', newline='') as file:
    has_header = csv.Sniffer().has_header(file.read(1024))
    file.seek(0)  # Rewind.
    reader = csv.reader(file)
    if has_header:
        next(reader)  # Skip header row.
    column = 1
    datatype = float
    data = (datatype(row[column]) for row in reader)
    least_value = min(data)

print(least_value)

以来datatypecolumnあなたの例ではハードコードされている、それが処理するために、わずかに速いだろうrow。このように:

    data = (float(row[1]) for row in reader)

注:上記のコードはPython 3.x用です。Python 2.xの場合、表示されているものの代わりに次の行を使用してファイルを開きます。

with open('all16.csv', 'rb') as file:

2
の代わりにhas_header(file.read(1024))、書くことは意味がありますhas_header(file.readline())か?たくさん見has_reader()ますが、CSVファイルの1行からヘッダーがあるかどうかを検出する方法を理解できません...
Anto

1
@Anto:私の回答のコードは、ドキュメンテーションの「Snifferの使用例」に基づいているため、規定された方法であると思います。1行のデータに基づいてそれを行うことは、そのような決定を行うのに常に十分なデータであるとは限らないことに同意します。ただし、動作がどのようSniffer記述されていないかわからないのです。FWIW私がしました決して見られないhas_header(file.readline())使用されていると、それはほとんどの時間を働いていた場合でも、私が述べた理由のためのアプローチの非常に疑わしいでしょう。
martineau 2018年

ご入力いただきありがとうございます。それにもかかわらず、使用file.read(1024) するとpythonのcsv libでエラーが生成されるようです:。たとえば、こちらもご覧ください。
Anto

@Anto:私はそのようなエラーに遭遇したことはありません-結局のところ1024バイトは大量のメモリではありません-また、この回答が受け取った賛成票(および数千のドキュメンテーションを読んで従った人々の)。これらの理由から、他の問題が問題を引き起こしていると強く思います。
martineau

からに切り替えた直後に、まったく同じエラーが発生しreadline()ましたread(1024)。これまでのところ、csv.dialectの問題を解決するためにreadlineに切り替えた人を見つけることができました。
Anto

75

最初の行をスキップするには、次を呼び出します。

next(inf)

Pythonのファイルは、行の反復子です。


22

同様の使用例では、迷惑な行を実際の列名のある行の前にスキップする必要がありました。このソリューションはうまく機能しました。最初にファイルを読み取り、次にリストをに渡しますcsv.DictReader

with open('all16.csv') as tmp:
    # Skip first line (if any)
    next(tmp, None)

    # {line_num: row}
    data = dict(enumerate(csv.DictReader(tmp)))

Veedracに感謝します。ここで学んで嬉しいですが、あなたが引用する問題を解決する編集を提案できますか?私の解決策は仕事を成し遂げましたが、それはさらに改善できるように見えますか?
Maarten、2015年

1
私はあなたに、コードを同一でなければならない(テストされていない)ものに置き換える編集をしました。それがあなたの意味と一致していない場合は、遠慮なく元に戻してください。なぜあなたがdata辞書を作っているのかはまだわかりませんし、この答えが受け入れられた辞書に本当に何かを追加することもありません。
Veedrac、2015年

ありがとうVeedrac!それは確かに非常に効率的に見えます。承認された回答が機能しなかったため、回答を投稿しました(理由を思い出せません)。data = dict()を定義し、すぐにそれを埋める(あなたの提案と比較して)問題は何でしょうか?
Maarten

1
そうではありません間違って行うことdata = dict()とそれを記入し、それは非効率的かつ慣用的ではありません。さらに、dictリテラル({})を使用する必要がありますenumerate
Veedrac、2015年

1
FWIW、@Veedracスタックオーバーフローはユーザー名から推測できるようですが、確実に通知を受け取りたい場合は、私の投稿に返信してください。(@Maarten回答者にはデフォルトで通知されるため、私は書きません。)
Veedrac '28

21

Pythonクックブックから借用した、
より簡潔なテンプレートコードは次のようになります。

import csv
with open('stocks.csv') as f:
    f_csv = csv.reader(f) 
    headers = next(f_csv) 
    for row in f_csv:
        # Process row ...

19

next(incsv)イテレータを1行進める通常使用するため、ヘッダーをスキップします。もう1つ(30行をスキップしたいとします)は次のようになります。

from itertools import islice
for row in islice(incsv, 30, None):
    # process

6

csv.Readerの代わりにcsv.DictReaderを使用してください。fieldnamesパラメータを省略すると、csvfileの最初の行の値がフィールド名として使用されます。その後、row ["1"]などを使用してフィールド値にアクセスできます


2

新しい 'pandas'パッケージは 'csv'よりも関連性が高いかもしれません。以下のコードはCSVファイルを読み取り、デフォルトでは最初の行を列ヘッダーとして解釈し、列全体の最小値を見つけます。

import pandas as pd

data = pd.read_csv('all16.csv')
data.min()

また、1行で記述することもできますpd.read_csv('all16.csv').min()
。– FinnÅrupNielsen 2014

1

まあ、私のミニラッパーライブラリーも同様に機能します。

>>> import pyexcel as pe
>>> data = pe.load('all16.csv', name_columns_by_row=0)
>>> min(data.column[1])

一方、たとえば「列1」など、ヘッダー列のインデックス1がわかっている場合は、代わりに次のように実行できます。

>>> min(data.column["Column 1"])

1

私にとって最も簡単な方法は、範囲を使用することです。

import csv

with open('files/filename.csv') as I:
    reader = csv.reader(I)
    fulllist = list(reader)

# Starting with data skipping header
for item in range(1, len(fulllist)): 
    # Print each row using "item" as the index value
    print (fulllist[item])  

1

これは私がやっていたことに関連しているので、ここで共有します。

ヘッダーがあるかどうかわからず、スニファーなどをインポートしたくない場合はどうなりますか?

リストや配列への出力や追加など、タスクが基本的な場合は、ifステートメントを使用するだけです。

# Let's say there's 4 columns
with open('file.csv') as csvfile:
     csvreader = csv.reader(csvfile)
# read first line
     first_line = next(csvreader)
# My headers were just text. You can use any suitable conditional here
     if len(first_line) == 4:
          array.append(first_line)
# Now we'll just iterate over everything else as usual:
     for row in csvreader:
          array.append(row)

1

Python 3 CSVモジュールドキュメントはこの例を提供します:

with open('example.csv', newline='') as csvfile:
    dialect = csv.Sniffer().sniff(csvfile.read(1024))
    csvfile.seek(0)
    reader = csv.reader(csvfile, dialect)
    # ... process CSV file contents here ...

SnifferCSVファイルについて多くのことを自動検出しようとします。has_header()ファイルにヘッダー行があるかどうかを判断するには、そのメソッドを明示的に呼び出す必要があります。含まれている場合は、CSV行を反復するときに最初の行をスキップします。あなたはこのようにそれを行うことができます:

if sniffer.has_header():
    for header_row in reader:
        break
for data_row in reader:
    # do something with the row

0

私は不要な最初の行を取り除くためにテールを使用します:

tail -n +2 $INFIL | whatever_script.py 

0

[1:]を追加するだけです

以下の例:

data = pd.read_csv("/Users/xyz/Desktop/xyxData/xyz.csv", sep=',', header=None)**[1:]**

それは私のためにiPythonで動作します


0

Python 3.X

UTF8 BOM + HEADERを処理します

csvモジュールがヘッダーを簡単に取得できなかったことは非常にイライラしました。UTF-8BOM(ファイルの最初の文字)にもバグがあります。これは私だけがcsvモジュールを使用して動作します:

import csv

def read_csv(self, csv_path, delimiter):
    with open(csv_path, newline='', encoding='utf-8') as f:
        # https://bugs.python.org/issue7185
        # Remove UTF8 BOM.
        txt = f.read()[1:]

    # Remove header line.
    header = txt.splitlines()[:1]
    lines = txt.splitlines()[1:]

    # Convert to list.
    csv_rows = list(csv.reader(lines, delimiter=delimiter))

    for row in csv_rows:
        value = row[INDEX_HERE]

0

私はcsvreaderをリストに変換し、最初の要素をポップします

import csv        

with open(fileName, 'r') as csvfile:
        csvreader = csv.reader(csvfile)
        data = list(csvreader)               # Convert to list
        data.pop(0)                          # Removes the first row

        for row in data:
            print(row)

0

Python 2.x

csvreader.next()

リーダーの反復可能なオブジェクトの次の行を、現在の方言に従って解析されたリストとして返します。

csv_data = csv.reader(open('sample.csv'))
csv_data.next() # skip first row
for row in csv_data:
    print(row) # should print second row

Python 3.x

csvreader.__next__()

リーダーの反復可能なオブジェクトの次の行をリスト(オブジェクトがreader()から返された場合)またはdict(DictReaderインスタンスの場合)として返し、現在の方言に従って解析されます。通常、これはnext(reader)として呼び出す必要があります。

csv_data = csv.reader(open('sample.csv'))
csv_data.__next__() # skip first row
for row in csv_data:
    print(row) # should print second row
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.