pythonでcsvを読み込む
最近Pythonでcsvを読み込み、データを操作することが多くなりました。
そのため、これを機にPythonでcsvを操作できるライブラリはどのようなものがあるか調べることにしました。
本記事ではcsv読み込みに絞って比較したいと思います。
なお、csvデータは気象庁が公開している過去の気象データを使用させて頂いております。
気象庁ホームページ
csvデータを操作するライブラリ
pythonでcsvを操作できる以下のライブラリについて比較します。
- 標準機能・標準ライブラリ(csvモジュール)
- NumPy
- pandas
- Polars
標準機能・標準ライブラリでcsvを読み込む
ファイルオブジェクトのメソッド
まずは、pythonの標準機能のファイルオブジェクトのreadメソッドでcsvを読み込みます。
7. 入力と出力 — Python ドキュメント
with open("data/sample.csv") as csvfile:
data = csvfile.read()
print(data)
print("-------------")
print(type(data))
読み込んだdata/sample.csv
データ
東京 | 東京 | 東京 | 東京 | 東京 | 東京 | 東京 | 東京 | 東京 | |
---|---|---|---|---|---|---|---|---|---|
年月 | 平均気温(℃) | 平均気温(℃) | 平均気温(℃) | 平均蒸気圧(hPa) | 平均蒸気圧(hPa) | 平均蒸気圧(hPa) | 平均現地気圧(hPa) | 平均現地気圧(hPa) | 平均現地気圧(hPa) |
品質情報 | 均質番号 | 品質情報 | 均質番号 | 品質情報 | 均質番号 | ||||
1950/9 | 23.8 | 8 | 1 | 22.9 | 8 | 1 | 0 | 1 | |
1950/10 | 15.8 | 8 | 1 | 13.5 | 8 | 1 | 0 | 1 | |
1950/11 | 11.1 | 8 | 1 | 9.9 | 8 | 1 | 0 | 1 | |
1950/12 | 5.4 | 8 | 1 | 5.9 | 8 | 1 | 0 | 1 | |
1951/1 | 3.3 | 8 | 1 | 4.6 | 8 | 1 | 1017.2 | 8 | 1 |
1951/2 | 4.5 | 8 | 1 | 5.3 | 8 | 1 | 1015.2 | 8 | 1 |
1951/3 | 8.8 | 8 | 1 | 7.4 | 8 | 1 | 1014.5 | 8 | 1 |
1951/4 | 13.3 | 8 | 1 | 10.5 | 8 | 1 | 1015.1 | 8 | 1 |
1951/5 | 18.0 | 8 | 1 | 14.6 | 8 | 1 | 1011.1 | 8 | 1 |
1951/6 | 21.2 | 8 | 1 | 18.8 | 8 | 1 | 1007.3 | 8 | 1 |
1951/7 | 24.3 | 8 | 1 | 25.3 | 8 | 1 | 1009.8 | 8 | 1 |
1951/8 | 26.7 | 8 | 1 | 27.8 | 8 | 1 | 1010.7 | 8 | 1 |
出力結果(ファイルオブジェクトreadを使用)
,東京,東京,東京,東京,東京,東京,東京,東京,東京
年月,平均気温(℃),平均気温(℃),平均気温(℃),平均蒸気圧(hPa),平均蒸気圧(hPa),平均蒸気圧(hPa),平均現地気圧(hPa),平均現地気圧(hPa),平均現地気圧(hPa)
,,品質情報,均質番号,,品質情報,均質番号,,品質情報,均質番号
1950/9,23.8,8,1,22.9,8,1,,0,1
1950/10,15.8,8,1,13.5,8,1,,0,1
1950/11,11.1,8,1,9.9,8,1,,0,1
1950/12,5.4,8,1,5.9,8,1,,0,1
1951/1,3.3,8,1,4.6,8,1,1017.2,8,1
1951/2,4.5,8,1,5.3,8,1,1015.2,8,1
1951/3,8.8,8,1,7.4,8,1,1014.5,8,1
1951/4,13.3,8,1,10.5,8,1,1015.1,8,1
1951/5,18.0,8,1,14.6,8,1,1011.1,8,1
1951/6,21.2,8,1,18.8,8,1,1007.3,8,1
1951/7,24.3,8,1,25.3,8,1,1009.8,8,1
1951/8,26.7,8,1,27.8,8,1,1010.7,8,1
-------------
<class 'str'>
型がstringなので、こちらは使用する機会は少ないかもしれません。
csv
モジュール:reader
標準ライブラリ次に、pythonの標準ライブラリcsv
モジュールを使用してcsvを読み込みます。
csv --- CSV ファイルの読み書き — Python 3 ドキュメント
import csv
with open("data/sample.csv", newline="") as csvfile:
reader = csv.reader(csvfile)
data = [row for row in reader]
print(data)
print("-------------")
print(type(data))
出力結果(csv.readerを使用)
[['', '東京', '東京', '東京', '東京', '東京', '東京', '東京', '東京', '東京'], ['年月', '平均気温(℃)', '平均気温(℃)', '平均気温(℃)', '平均蒸気圧(hPa)', '平均蒸気圧(hPa)', '平均蒸気圧(hPa)', '平均現地気圧(hPa)', '平均現地気圧(hPa)', '平均現地気圧(hPa)'], ['', '', '品質情報', '均質番号', '', '品質情報', '均質番号', '', '品質情報', '均質番号'], ['1950/9', '23.8', '8', '1', '22.9', '8', '1', '', '0', '1'], ['1950/10', '15.8', '8', '1', '13.5', '8', '1', '', '0', '1'], ['1950/11', '11.1', '8', '1', '9.9', '8', '1', '', '0', '1'], ['1950/12', '5.4', '8', '1', '5.9', '8', '1', '', '0', '1'], ['1951/1', '3.3', '8', '1', '4.6', '8', '1', '1017.2', '8', '1'], ['1951/2', '4.5', '8', '1', '5.3', '8', '1', '1015.2', '8', '1'], ['1951/3', '8.8', '8', '1', '7.4', '8', '1', '1014.5', '8', '1'], ['1951/4', '13.3', '8', '1', '10.5', '8', '1', '1015.1', '8', '1'], ['1951/5', '18.0', '8', '1', '14.6', '8', '1', '1011.1', '8', '1'], ['1951/6', '21.2', '8', '1', '18.8', '8', '1', '1007.3', '8', '1'], ['1951/7', '24.3', '8', '1', '25.3', '8', '1', '1009.8', '8', '1'], ['1951/8', '26.7', '8', '1', '27.8', '8', '1', '1010.7', '8', '1']]
-------------
<class 'list'>
読み込んだcsvデータがlist型となりました。
csv
モジュール:DictReader
標準ライブラリ辞書型で読み込むこともできます。
import csv
with open('data/sample.csv', newline='') as csvfile:
reader = csv.DictReader(csvfile)
data = [row for row in reader]
print(data)
print("-------------")
print(type(data))
しかし、ヘッダーが複数行ある場合は以下のように正しく読み込めませんでした。
出力結果(csv.DictReaderを使用)
[{'': '年月', '東京': '平均現地気圧(hPa)'}, {'': '', '東京': '均質番号'}, {'': '1950/9', '東京': '1'}, {'': '1950/10', '東京': '1'}, {'': '1950/11', '東京': '1'}, {'': '1950/12', '東京': '1'}, {'': '1951/1', '東京': '1'}, {'': '1951/2', '東京': '1'}, {'': '1951/3', '東京': '1'}, {'': '1951/4', '東京': '1'}, {'': '1951/5', '東京': '1'}, {'': '1951/6', '東京': '1'}, {'': '1951/7', '東京': '1'}, {'': '1951/8', '東京': '1'}]
-------------
<class 'list'>
ヘッダーが1行しかなく、列の名称が一意の場合は正しく読み込めました。
import csv
with open('data/sample_2.csv', newline='') as csvfile:
reader = csv.DictReader(csvfile)
data = [row for row in reader]
print(data)
print("-------------")
print(type(data))
読み込んだdata/sample_2.csvのデータ
年月 | 平均気温(℃) | 平均蒸気圧(hPa) | 平均現地気圧(hPa) |
---|---|---|---|
1950/9 | 23.8 | 22.9 | |
1950/10 | 15.8 | 13.5 | |
1950/11 | 11.1 | 9.9 | |
1950/12 | 5.4 | 5.9 | |
1951/1 | 3.3 | 4.6 | 1017.2 |
1951/2 | 4.5 | 5.3 | 1015.2 |
1951/3 | 8.8 | 7.4 | 1014.5 |
1951/4 | 13.3 | 10.5 | 1015.1 |
1951/5 | 18.0 | 14.6 | 1011.1 |
1951/6 | 21.2 | 18.8 | 1007.3 |
1951/7 | 24.3 | 25.3 | 1009.8 |
1951/8 | 26.7 | 27.8 | 1010.7 |
出力結果
[{'年月': '1950/9', '平均気温(℃)': '23.8', '平均蒸気圧(hPa)': '22.9', '平均現地気圧(hPa)': ''}, {'年月': '1950/10', '平均気温(℃)': '15.8', '平均蒸気圧(hPa)': '13.5', '平均現地気圧(hPa)': ''}, {'年月': '1950/11', '平均気温(℃)': '11.1', '平均蒸気圧(hPa)': '9.9', '平均現地気圧(hPa)': ''}, {'年月': '1950/12', '平均気温(℃)': '5.4', '平均蒸気圧(hPa)': '5.9', '平均現地気圧(hPa)': ''}, {'年月': '1951/1', '平均気温(℃)': '3.3', '平均蒸気圧(hPa)': '4.6', '平均現地気圧(hPa)': '1017.2'}, {'年月': '1951/2', '平均気温(℃)': '4.5', '平均蒸気圧(hPa)': '5.3', '平均現地気圧(hPa)': '1015.2'}, {'年月': '1951/3', '平均気温(℃)': '8.8', '平均蒸気圧(hPa)': '7.4', '平均現地気圧(hPa)': '1014.5'}, {'年月': '1951/4', '平均気温(℃)': '13.3', '平均蒸気圧(hPa)': '10.5', '平均現地気圧(hPa)': '1015.1'}, {'年月': '1951/5', '平均気温(℃)': '18.0', '平均蒸気圧(hPa)': '14.6', '平均現地気圧(hPa)': '1011.1'}, {'年月': '1951/6', '平均気温(℃)': '21.2', '平均蒸気圧(hPa)': '18.8', '平均現地気圧(hPa)': '1007.3'}, {'年月': '1951/7', '平均気温(℃)': '24.3', '平均蒸気圧(hPa)': '25.3', '平均現地気圧(hPa)': '1009.8'}, {'年月': '1951/8', '平均気温(℃)': '26.7', '平均蒸気圧(hPa)': '27.8', '平均現地気圧(hPa)': '1010.7'}]
-------------
<class 'list'>
NumPyでcsv読み込み
NumPyを使用してcsvを読み込みます。
import numpy as np
sample = np.loadtxt("data/sample.csv", delimiter=",", dtype="unicode")
print(sample)
print("-------------")
print(type(sample))
csvファイルの場合、引数:delimiter=","
を指定しないとエラーになります。
また、csvデータ内に数字以外の値が存在する場合エラーとなります。
日本語が含まれている場合はdtype="unicode"
を指定します。
出力結果(読み込み成功)
[['' '東京' '東京' '東京' '東京' '東京' '東京' '東京' '東京' '東京']
['年月' '平均気温(℃)' '平均気温(℃)' '平均気温(℃)' '平均蒸気圧(hPa)' '平均蒸気圧(hPa)'
'平均蒸気圧(hPa)' '平均現地気圧(hPa)' '平均現地気圧(hPa)' '平均現地気圧(hPa)']
['' '' '品質情報' '均質番号' '' '品質情報' '均質番号' '' '品質情報' '均質番号']
['1950/9' '23.8' '8' '1' '22.9' '8' '1' '' '0' '1']
['1950/10' '15.8' '8' '1' '13.5' '8' '1' '' '0' '1']
['1950/11' '11.1' '8' '1' '9.9' '8' '1' '' '0' '1']
['1950/12' '5.4' '8' '1' '5.9' '8' '1' '' '0' '1']
['1951/1' '3.3' '8' '1' '4.6' '8' '1' '1017.2' '8' '1']
['1951/2' '4.5' '8' '1' '5.3' '8' '1' '1015.2' '8' '1']
['1951/3' '8.8' '8' '1' '7.4' '8' '1' '1014.5' '8' '1']
['1951/4' '13.3' '8' '1' '10.5' '8' '1' '1015.1' '8' '1']
['1951/5' '18.0' '8' '1' '14.6' '8' '1' '1011.1' '8' '1']
['1951/6' '21.2' '8' '1' '18.8' '8' '1' '1007.3' '8' '1']
['1951/7' '24.3' '8' '1' '25.3' '8' '1' '1009.8' '8' '1']
['1951/8' '26.7' '8' '1' '27.8' '8' '1' '1010.7' '8' '1']]
-------------
<class 'numpy.ndarray'>
読み込み失敗(delimiter,dtype指定なし)
import numpy as np
sample = np.loadtxt("data/sample.csv")
print(sample)
print("-------------")
print(type(sample))
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
ValueError: could not convert string to float: ','
The above exception was the direct cause of the following exception:
ValueError Traceback (most recent call last)
Cell In[8], line 3
1 import numpy as np
----> 3 sample = np.loadtxt("data/sample.csv")
4 print(sample)
5 print("-------------")
ValueError: could not convert string ',東京,東京,東京,東京,東京,東京,東京,東京,東京' to float64 at row 0, column 1.
読み込み失敗(dtype指定なし)
import numpy as np
sample = np.loadtxt("data/sample.csv", delimiter=",")
print(sample)
print("-------------")
print(type(sample))
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Cell In[9], line 3
1 import numpy as np
----> 3 sample = np.loadtxt("data/sample.csv", delimiter=",")
4 print(sample)
5 print("-------------")
ValueError: could not convert string '' to float64 at row 0, column 1.
pandasでcsv読み込み
pandasでcsvを読み込みます。
pandas.read_csv — pandas documentation
import pandas as pd
df = pd.read_csv('data/sample.csv')
print(df)
print("-------------")
print(type(df))
pandasで読み込んだdata/sample.csv
データ
Unnamed: 0 東京 東京.1 東京.2 東京.3 東京.4 東京.5 \
0 年月 平均気温(℃) 平均気温(℃) 平均気温(℃) 平均蒸気圧(hPa) 平均蒸気圧(hPa) 平均蒸気圧(hPa)
1 NaN NaN 品質情報 均質番号 NaN 品質情報 均質番号
2 1950/9 23.8 8 1 22.9 8 1
3 1950/10 15.8 8 1 13.5 8 1
4 1950/11 11.1 8 1 9.9 8 1
5 1950/12 5.4 8 1 5.9 8 1
6 1951/1 3.3 8 1 4.6 8 1
7 1951/2 4.5 8 1 5.3 8 1
8 1951/3 8.8 8 1 7.4 8 1
9 1951/4 13.3 8 1 10.5 8 1
10 1951/5 18.0 8 1 14.6 8 1
11 1951/6 21.2 8 1 18.8 8 1
12 1951/7 24.3 8 1 25.3 8 1
13 1951/8 26.7 8 1 27.8 8 1
東京.6 東京.7 東京.8
0 平均現地気圧(hPa) 平均現地気圧(hPa) 平均現地気圧(hPa)
1 NaN 品質情報 均質番号
2 NaN 0 1
3 NaN 0 1
4 NaN 0 1
5 NaN 0 1
6 1017.2 8 1
7 1015.2 8 1
8 1014.5 8 1
9 1015.1 8 1
10 1011.1 8 1
11 1007.3 8 1
12 1009.8 8 1
13 1010.7 8 1
-------------
<class 'pandas.core.frame.DataFrame'>
行ラベル、列名を指定していない場合、自動で1行目がcolumn、2行目からindexは0から連番で振られます。
空白セル(None)はNaN
(欠損値)と表示されます。
以下のようにindex_col
に列名や列番号を指定したり、headerに列名の行を指定することもできます。
import pandas as pd
df = pd.read_csv('data/sample.csv', index_col=0, header=[0,1,2])
print(df)
print("-------------")
print(type(df))
pandas:index_col,headerを指定して読み込み
東京 \
年月 平均気温(℃) 平均蒸気圧(hPa)
Unnamed: 1_level_2 品質情報 均質番号 Unnamed: 4_level_2 品質情報 均質番号
1950/9 23.8 8 1 22.9 8 1
1950/10 15.8 8 1 13.5 8 1
1950/11 11.1 8 1 9.9 8 1
1950/12 5.4 8 1 5.9 8 1
1951/1 3.3 8 1 4.6 8 1
1951/2 4.5 8 1 5.3 8 1
1951/3 8.8 8 1 7.4 8 1
1951/4 13.3 8 1 10.5 8 1
1951/5 18.0 8 1 14.6 8 1
1951/6 21.2 8 1 18.8 8 1
1951/7 24.3 8 1 25.3 8 1
1951/8 26.7 8 1 27.8 8 1
年月 平均現地気圧(hPa)
Unnamed: 7_level_2 品質情報 均質番号
1950/9 NaN 0 1
1950/10 NaN 0 1
1950/11 NaN 0 1
1950/12 NaN 0 1
1951/1 1017.2 8 1
1951/2 1015.2 8 1
1951/3 1014.5 8 1
1951/4 1015.1 8 1
1951/5 1011.1 8 1
1951/6 1007.3 8 1
1951/7 1009.8 8 1
1951/8 1010.7 8 1
-------------
<class 'pandas.core.frame.DataFrame'>
以下のように列名を別名で指定してcsvを読み込むことも可能です。
import pandas as pd
df = pd.read_csv(
"data/sample.csv",
names=[
"年月",
"平均気温(℃)",
"平均気温(℃)_品質情報",
"平均気温(℃)_均質番号",
"平均蒸気圧(hPa)",
"平均蒸気圧(hPa)_品質情報",
"平均蒸気圧(hPa)_均質番号",
"平均現地気圧(hPa)",
"平均現地気圧(hPa)_品質情報",
"平均現地気圧(hPa)_均質番号",
],
index_col=0,
skiprows=3,
)
print(df)
print("-------------")
print(type(df))
pandas:列名を指定して読み込み
平均気温(℃) 平均気温(℃)_品質情報 平均気温(℃)_均質番号 平均蒸気圧(hPa) 平均蒸気圧(hPa)_品質情報 \
年月
1950/9 23.8 8 1 22.9 8
1950/10 15.8 8 1 13.5 8
1950/11 11.1 8 1 9.9 8
1950/12 5.4 8 1 5.9 8
1951/1 3.3 8 1 4.6 8
1951/2 4.5 8 1 5.3 8
1951/3 8.8 8 1 7.4 8
1951/4 13.3 8 1 10.5 8
1951/5 18.0 8 1 14.6 8
1951/6 21.2 8 1 18.8 8
1951/7 24.3 8 1 25.3 8
1951/8 26.7 8 1 27.8 8
平均蒸気圧(hPa)_均質番号 平均現地気圧(hPa) 平均現地気圧(hPa)_品質情報 平均現地気圧(hPa)_均質番号
年月
1950/9 1 NaN 0 1
1950/10 1 NaN 0 1
1950/11 1 NaN 0 1
1950/12 1 NaN 0 1
1951/1 1 1017.2 8 1
1951/2 1 1015.2 8 1
1951/3 1 1014.5 8 1
1951/4 1 1015.1 8 1
1951/5 1 1011.1 8 1
1951/6 1 1007.3 8 1
1951/7 1 1009.8 8 1
1951/8 1 1010.7 8 1
-------------
<class 'pandas.core.frame.DataFrame'>
Polarsでcsv読み込み
Polarsでcsvを読み込みます。
polars.read_csv — Polars documentation
import polars as pl
df = pl.read_csv('data/sample.csv')
print(df)
print("-------------")
print(type(df))
polarsで読み込んだdata/sample.csv
データ
shape: (14, 10)
┌─────────┬────┬────────────┬────────────┬─────┬────────────┬────────────┬────────────┬────────────┐
│ ┆ 東 ┆ 東京_dupli ┆ 東京_dupli ┆ ... ┆ 東京_dupli ┆ 東京_dupli ┆ 東京_dupli ┆ 東京_dupli │
│ --- ┆ 京 ┆ cated_0 ┆ cated_1 ┆ ┆ cated_4 ┆ cated_5 ┆ cated_6 ┆ cated_7 │
│ str ┆ -- ┆ --- ┆ --- ┆ ┆ --- ┆ --- ┆ --- ┆ --- │
│ ┆ - ┆ str ┆ str ┆ ┆ str ┆ str ┆ str ┆ str │
│ ┆ st ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ ┆ r ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
╞═════════╪════╪════════════╪════════════╪═════╪════════════╪════════════╪════════════╪════════════╡
│ 年月 ┆ 平 ┆ 平均気温(℃ ┆ 平均気温(℃ ┆ ... ┆ 平均蒸気圧 ┆ 平均現地気 ┆ 平均現地気 ┆ 平均現地気 │
│ ┆ 均 ┆ ) ┆ ) ┆ ┆ (hPa) ┆ 圧(hPa) ┆ 圧(hPa) ┆ 圧(hPa) │
│ ┆ 気 ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ ┆ 温 ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ ┆ (℃ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ ┆ ) ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ null ┆ nu ┆ 品質情報 ┆ 均質番号 ┆ ... ┆ 均質番号 ┆ null ┆ 品質情報 ┆ 均質番号 │
│ ┆ ll ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ 1950/9 ┆ 23 ┆ 8 ┆ 1 ┆ ... ┆ 1 ┆ null ┆ 0 ┆ 1 │
│ ┆ .8 ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ 1950/10 ┆ 15 ┆ 8 ┆ 1 ┆ ... ┆ 1 ┆ null ┆ 0 ┆ 1 │
│ ┆ .8 ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ ... ┆ .. ┆ ... ┆ ... ┆ ... ┆ ... ┆ ... ┆ ... ┆ ... │
│ ┆ . ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ 1951/5 ┆ 18 ┆ 8 ┆ 1 ┆ ... ┆ 1 ┆ 1011.1 ┆ 8 ┆ 1 │
│ ┆ .0 ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ 1951/6 ┆ 21 ┆ 8 ┆ 1 ┆ ... ┆ 1 ┆ 1007.3 ┆ 8 ┆ 1 │
│ ┆ .2 ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ 1951/7 ┆ 24 ┆ 8 ┆ 1 ┆ ... ┆ 1 ┆ 1009.8 ┆ 8 ┆ 1 │
│ ┆ .3 ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ 1951/8 ┆ 26 ┆ 8 ┆ 1 ┆ ... ┆ 1 ┆ 1010.7 ┆ 8 ┆ 1 │
│ ┆ .7 ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
└─────────┴────┴────────────┴────────────┴─────┴────────────┴────────────┴────────────┴────────────┘
-------------
<class 'polars.internals.dataframe.frame.DataFrame'>
polarsの場合、空白セル(None)はnull
と表示されます。
Process missing data - Polars - User Guide
skip_rows
を指定することで、指定した行数の次の行から読み込みます。
import polars as pl
df = pl.read_csv('data/sample.csv', skip_rows=2)
print(df)
print("-------------")
print(type(df))
polars:skip_rowsを指定して読み込み
shape: (12, 10)
┌─────────┬────────────┬────────────┬────────────┬─────┬────────────┬────────────┬────────────┬────────────┐
│ ┆ _duplicate ┆ 品質情報 ┆ 均質番号 ┆ ... ┆ 均質番号_d ┆ _duplicate ┆ 品質情報_d ┆ 均質番号_d │
│ --- ┆ d_0 ┆ --- ┆ --- ┆ ┆ uplicated_ ┆ d_2 ┆ uplicated_ ┆ uplicated_ │
│ str ┆ --- ┆ i64 ┆ i64 ┆ ┆ 0 ┆ --- ┆ 1 ┆ 1 │
│ ┆ f64 ┆ ┆ ┆ ┆ --- ┆ f64 ┆ --- ┆ --- │
│ ┆ ┆ ┆ ┆ ┆ i64 ┆ ┆ i64 ┆ i64 │
╞═════════╪════════════╪════════════╪════════════╪═════╪════════════╪════════════╪════════════╪════════════╡
│ 1950/9 ┆ 23.8 ┆ 8 ┆ 1 ┆ ... ┆ 1 ┆ null ┆ 0 ┆ 1 │
│ 1950/10 ┆ 15.8 ┆ 8 ┆ 1 ┆ ... ┆ 1 ┆ null ┆ 0 ┆ 1 │
│ 1950/11 ┆ 11.1 ┆ 8 ┆ 1 ┆ ... ┆ 1 ┆ null ┆ 0 ┆ 1 │
│ 1950/12 ┆ 5.4 ┆ 8 ┆ 1 ┆ ... ┆ 1 ┆ null ┆ 0 ┆ 1 │
│ ... ┆ ... ┆ ... ┆ ... ┆ ... ┆ ... ┆ ... ┆ ... ┆ ... │
│ 1951/5 ┆ 18.0 ┆ 8 ┆ 1 ┆ ... ┆ 1 ┆ 1011.1 ┆ 8 ┆ 1 │
│ 1951/6 ┆ 21.2 ┆ 8 ┆ 1 ┆ ... ┆ 1 ┆ 1007.3 ┆ 8 ┆ 1 │
│ 1951/7 ┆ 24.3 ┆ 8 ┆ 1 ┆ ... ┆ 1 ┆ 1009.8 ┆ 8 ┆ 1 │
│ 1951/8 ┆ 26.7 ┆ 8 ┆ 1 ┆ ... ┆ 1 ┆ 1010.7 ┆ 8 ┆ 1 │
└─────────┴────────────┴────────────┴────────────┴─────┴────────────┴────────────┴────────────┴────────────┘
-------------
<class 'polars.internals.dataframe.frame.DataFrame'>
polarsは2行以上のヘッダーを指定できないようです。
has_header=False
と指定すると、すべての行がデータとして読み込まれ、列名はcolumn_x
(x
は1から連番)という名称が自動で生成されます。
import polars as pl
df = pl.read_csv('data/sample.csv', has_header=False)
print(df)
print("-------------")
print(type(df))
polars:has_header=Falseを指定して読み込み
shape: (15, 10)
┌──────────┬───────────┬───────────┬───────────┬─────┬───────────┬───────────┬───────────┬─────────┐
│ column_1 ┆ column_2 ┆ column_3 ┆ column_4 ┆ ... ┆ column_7 ┆ column_8 ┆ column_9 ┆ column_ │
│ --- ┆ --- ┆ --- ┆ --- ┆ ┆ --- ┆ --- ┆ --- ┆ 10 │
│ str ┆ str ┆ str ┆ str ┆ ┆ str ┆ str ┆ str ┆ --- │
│ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ str │
╞══════════╪═══════════╪═══════════╪═══════════╪═════╪═══════════╪═══════════╪═══════════╪═════════╡
│ null ┆ 東京 ┆ 東京 ┆ 東京 ┆ ... ┆ 東京 ┆ 東京 ┆ 東京 ┆ 東京 │
│ 年月 ┆ 平均気温( ┆ 平均気温( ┆ 平均気温( ┆ ... ┆ 平均蒸気 ┆ 平均現地 ┆ 平均現地 ┆ 平均現 │
│ ┆ ℃) ┆ ℃) ┆ ℃) ┆ ┆ 圧(hPa) ┆ 気圧(hPa) ┆ 気圧(hPa) ┆ 地気圧( │
│ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ hPa) │
│ null ┆ null ┆ 品質情報 ┆ 均質番号 ┆ ... ┆ 均質番号 ┆ null ┆ 品質情報 ┆ 均質番 │
│ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 号 │
│ 1950/9 ┆ 23.8 ┆ 8 ┆ 1 ┆ ... ┆ 1 ┆ null ┆ 0 ┆ 1 │
│ ... ┆ ... ┆ ... ┆ ... ┆ ... ┆ ... ┆ ... ┆ ... ┆ ... │
│ 1951/5 ┆ 18.0 ┆ 8 ┆ 1 ┆ ... ┆ 1 ┆ 1011.1 ┆ 8 ┆ 1 │
│ 1951/6 ┆ 21.2 ┆ 8 ┆ 1 ┆ ... ┆ 1 ┆ 1007.3 ┆ 8 ┆ 1 │
│ 1951/7 ┆ 24.3 ┆ 8 ┆ 1 ┆ ... ┆ 1 ┆ 1009.8 ┆ 8 ┆ 1 │
│ 1951/8 ┆ 26.7 ┆ 8 ┆ 1 ┆ ... ┆ 1 ┆ 1010.7 ┆ 8 ┆ 1 │
└──────────┴───────────┴───────────┴───────────┴─────┴───────────┴───────────┴───────────┴─────────┘
-------------
<class 'polars.internals.dataframe.frame.DataFrame'>
polarsも以下のように列名を別名で指定してcsvを読み込むことも可能です。
import polars as pl
df = pl.read_csv(
"data/sample.csv",
skip_rows=2,
new_columns=[
"年月",
"平均気温(℃)",
"平均気温(℃)_品質情報",
"平均気温(℃)_均質番号",
"平均蒸気圧(hPa)",
"平均蒸気圧(hPa)_品質情報",
"平均蒸気圧(hPa)_均質番号",
"平均現地気圧(hPa)",
"平均現地気圧(hPa)_品質情報",
"平均現地気圧(hPa)_均質番号",
]
)
print(df)
print("-------------")
print(type(df))
polars:new_columnsを指定して読み込み
shape: (12, 10)
┌─────────┬────────────┬────────────┬────────────┬─────┬────────────┬────────────┬────────────┬────────────┐
│ 年月 ┆ 平均気温(℃ ┆ 平均気温(℃ ┆ 平均気温(℃ ┆ ... ┆ 平均蒸気圧 ┆ 平均現地気 ┆ 平均現地気 ┆ 平均現地気 │
│ --- ┆ ) ┆ )_品質情報 ┆ )_均質番号 ┆ ┆ (hPa)_均質 ┆ 圧(hPa) ┆ 圧(hPa)_品 ┆ 圧(hPa)_均 │
│ str ┆ --- ┆ --- ┆ --- ┆ ┆ 番号 ┆ --- ┆ 質情報 ┆ 質番号 │
│ ┆ f64 ┆ i64 ┆ i64 ┆ ┆ --- ┆ f64 ┆ --- ┆ --- │
│ ┆ ┆ ┆ ┆ ┆ i64 ┆ ┆ i64 ┆ i64 │
╞═════════╪════════════╪════════════╪════════════╪═════╪════════════╪════════════╪════════════╪════════════╡
│ 1950/9 ┆ 23.8 ┆ 8 ┆ 1 ┆ ... ┆ 1 ┆ null ┆ 0 ┆ 1 │
│ 1950/10 ┆ 15.8 ┆ 8 ┆ 1 ┆ ... ┆ 1 ┆ null ┆ 0 ┆ 1 │
│ 1950/11 ┆ 11.1 ┆ 8 ┆ 1 ┆ ... ┆ 1 ┆ null ┆ 0 ┆ 1 │
│ 1950/12 ┆ 5.4 ┆ 8 ┆ 1 ┆ ... ┆ 1 ┆ null ┆ 0 ┆ 1 │
│ ... ┆ ... ┆ ... ┆ ... ┆ ... ┆ ... ┆ ... ┆ ... ┆ ... │
│ 1951/5 ┆ 18.0 ┆ 8 ┆ 1 ┆ ... ┆ 1 ┆ 1011.1 ┆ 8 ┆ 1 │
│ 1951/6 ┆ 21.2 ┆ 8 ┆ 1 ┆ ... ┆ 1 ┆ 1007.3 ┆ 8 ┆ 1 │
│ 1951/7 ┆ 24.3 ┆ 8 ┆ 1 ┆ ... ┆ 1 ┆ 1009.8 ┆ 8 ┆ 1 │
│ 1951/8 ┆ 26.7 ┆ 8 ┆ 1 ┆ ... ┆ 1 ┆ 1010.7 ┆ 8 ┆ 1 │
└─────────┴────────────┴────────────┴────────────┴─────┴────────────┴────────────┴────────────┴────────────┘
-------------
<class 'polars.internals.dataframe.frame.DataFrame'>
まとめ
個人的感想
今回はpythonでcsvを読み込みについて記載しました。
単純なcsvを読み込むだけの場合は、標準ライブラリの使用で問題なさそうです。
しかし、csvを読み込んでデータを操作・編集したい場合は処理が複雑になりそうなので、NumPy, pandasやpolarsを使用したほうが効率がよさそうに感じました。
NumPy,pandas,polarsはcsv読み込み処理については大きな違いはありませんでした。
そのため、csvを読み込んだデータの型によって使い方が変わってくると思います。
以下にデータ型をまとめます。
各ライブラリと型の比較表
ライブラリのメソッド | csv読み込み後のデータの型 |
---|---|
ファイルオブジェクトread | string |
csv.reader | list |
csv.DictReader | [dict] |
numpy.loadtxt | numpy.ndarray |
pandas.read_csv | pandas.core.frame.DataFrame |
polars.read_csv | polars.internals.dataframe.frame.DataFrame |
他の処理について別の機会にまとめようと思います。
Discussion