Open In Colab

Pandasの使い方 (基礎)#

Pandasは、データ分析のためのライブラリで
統計量を計算・表示したり、それらをグラフとして可視化出来たり
前処理などの地道だが重要な作業を比較的簡単に行うことができる。

まずはインポートしよう。pdという名前で使うのが慣例。

import pandas as pd 
import numpy as np #numpyもどうせ使う

pandasでは主にSeriesDataFrameの2つのオブジェクトを扱う。
SeriesDataFrameの特殊な場合とみなせるので、以下ではDataFrameのみ説明することにする。

なお、Web上のデータを読み込む際に、User-Agentを指定しないとアクセスできない場合がある。その際は

storage_options = {'User-Agent': 'Mozilla/5.0'}

などを引数に追加して試してみよう。

DataFrame型#

DataFrameはExcelシートのような二次元のデータを表現するのに利用され各種データ分析などで非常に役に立つ。

from pandas import DataFrame

以下の辞書型をDataFrameのオブジェクトに変換してみましょう。

data = { '名前': ["Aさん", "Bさん", "Cさん", "Dさん", "Eさん"],
        '出身都道府県':['Tokyo', 'Tochigi', 'Hokkaido','Kyoto','Tochigi'],
        '生年': [ 1998, 1993,2000,1989,2002],
        '身長': [172, 156, 162, 180,158]}
df = DataFrame(data)
print("dataの型", type(data))
print("dfの型",type(df))
dataの型 <class 'dict'>
dfの型 <class 'pandas.DataFrame'>

jupyter環境でDataFrameをコードセルの最終行に書くと、”いい感じ”に表示してくれる

df
名前 出身都道府県 生年 身長
0 Aさん Tokyo 1998 172
1 Bさん Tochigi 1993 156
2 Cさん Hokkaido 2000 162
3 Dさん Kyoto 1989 180
4 Eさん Tochigi 2002 158

printだとちょっと無機質な感じに。

print(df)
    名前    出身都道府県    生年   身長
0  Aさん     Tokyo  1998  172
1  Bさん   Tochigi  1993  156
2  Cさん  Hokkaido  2000  162
3  Dさん     Kyoto  1989  180
4  Eさん   Tochigi  2002  158

単一のコードセルの途中でDataFrameを表示したい場合などは、display関数を使うと良い。

display(df)
名前 出身都道府県 生年 身長
0 Aさん Tokyo 1998 172
1 Bさん Tochigi 1993 156
2 Cさん Hokkaido 2000 162
3 Dさん Kyoto 1989 180
4 Eさん Tochigi 2002 158

info()関数を作用させると、詳細な情報が得られる。
列ごとにどんな種類のデータが格納されているのかや、 メモリ使用量など表示することができる。

df.info()
<class 'pandas.DataFrame'>
RangeIndex: 5 entries, 0 to 4
Data columns (total 4 columns):
 #   Column  Non-Null Count  Dtype
---  ------  --------------  -----
 0   名前      5 non-null      str  
 1   出身都道府県  5 non-null      str  
 2   生年      5 non-null      int64
 3   身長      5 non-null      int64
dtypes: int64(2), str(2)
memory usage: 292.0 bytes

DataFrameの要素を確認・指定する方法#

index: 行方向のデータ項目(おもに整数値(行番号),ID,名前など)
columns: 列方向のデータの項目(おもにデータの種類)
をそれぞれ表示してみよう。

df.index
RangeIndex(start=0, stop=5, step=1)
df.columns
Index(['名前', '出身都道府県', '生年', '身長'], dtype='str')

行方向を、整数値(行数)ではなく名前にしたければ

data1 = {'出身都道府県':['Tokyo', 'Tochigi', 'Hokkaido','Kyoto','Tochigi'],
        '生年': [ 1998, 1993,2000,1989,2002],
        '身長': [172, 156, 162, 180,158]}
df = DataFrame(data1)
df.index =["Aさん", "Bさん", "Cさん", "Dさん", "Eさん"]
df
出身都道府県 生年 身長
Aさん Tokyo 1998 172
Bさん Tochigi 1993 156
Cさん Hokkaido 2000 162
Dさん Kyoto 1989 180
Eさん Tochigi 2002 158

などとしてもよい。

特定の列を取得したい場合#

df["身長"]
Aさん    172
Bさん    156
Cさん    162
Dさん    180
Eさん    158
Name: 身長, dtype: int64

と列名を指定すればよい。
以下の方法でも取得できるが、この授業では非推奨とする。

df.身長
Aさん    172
Bさん    156
Cさん    162
Dさん    180
Eさん    158
Name: 身長, dtype: int64

値のリスト(正確にはnumpy.ndarray型)として取得したければ

df["身長"].values
array([172, 156, 162, 180, 158])
df["出身都道府県"].values
<StringArray>
['Tokyo', 'Tochigi', 'Hokkaido', 'Kyoto', 'Tochigi']
Length: 5, dtype: str

などとすればよい。

慣れ親しんだ形に変換したければ、リストに変換すればよい

list(df["出身都道府県"].values)
['Tokyo', 'Tochigi', 'Hokkaido', 'Kyoto', 'Tochigi']

また、列名の配列を指定することで、複数の列を取得することもできる。

df[["出身都道府県", "生年"]]
出身都道府県 生年
Aさん Tokyo 1998
Bさん Tochigi 1993
Cさん Hokkaido 2000
Dさん Kyoto 1989
Eさん Tochigi 2002

ある列が特定のものに一致するもののみを抽出するのも簡単にできる

df[df["出身都道府県"]=="Tochigi"]
出身都道府県 生年 身長
Bさん Tochigi 1993 156
Eさん Tochigi 2002 158

これは

df["出身都道府県"]=="Tochigi"
Aさん    False
Bさん     True
Cさん    False
Dさん    False
Eさん     True
Name: 出身都道府県, dtype: bool

が条件に合致するかどうかTrue/Falseの配列(正確にはSeries)になっていて、
df[ [True/Falseの配列] ]とすると、Trueに対応する要素のみを返すフィルターのような役割になっている。

このように、特定の条件に応じて抽出した(フィルタリングやマスクなどとも呼ぶ)データを使って、さらに分析を進めることができる。 もとのDataFrameから上記のような方法で抽出したものもDataFrame型のオブジェクトになるため、 抽出したものの中から特定の列を選ぶ場合などは、同じようにして行うことができる。

出身都道府県の列が”Tochigi”の人を抽出し、その”生年”の列を取得する例は以下のようになる。

df[df["出身都道府県"]=="Tochigi"]["生年"]
Bさん    1993
Eさん    2002
Name: 生年, dtype: int64
df[df["出身都道府県"]=="Tochigi"]

部分もDataFrame型のオブジェクトになっている

type( df[df["出身都道府県"]=="Tochigi"] )
pandas.DataFrame

列の追加#

#スカラー値の場合"初期化"のような振る舞いをする
df["血液型"] = "A"
df
出身都道府県 生年 身長 血液型
Aさん Tokyo 1998 172 A
Bさん Tochigi 1993 156 A
Cさん Hokkaido 2000 162 A
Dさん Kyoto 1989 180 A
Eさん Tochigi 2002 158 A
df["血液型"] = "B"
df
出身都道府県 生年 身長 血液型
Aさん Tokyo 1998 172 B
Bさん Tochigi 1993 156 B
Cさん Hokkaido 2000 162 B
Dさん Kyoto 1989 180 B
Eさん Tochigi 2002 158 B

リストやnumpy.ndarrayを列として追加することができる。

#リストで追加
df["血液型"] = [ "A", "O","AB","B","A"]
df
出身都道府県 生年 身長 血液型
Aさん Tokyo 1998 172 A
Bさん Tochigi 1993 156 O
Cさん Hokkaido 2000 162 AB
Dさん Kyoto 1989 180 B
Eさん Tochigi 2002 158 A

特定の行を取得したい場合#

たとえば、行番号がわかっているなら、iloc関数を使えば良い

df.iloc[3]
出身都道府県    Kyoto
生年         1989
身長          180
血液型           B
Name: Dさん, dtype: object

値のみ取得したければ先程と同様valuesnumpy.ndarrayを取得できる

df.iloc[3].values
array(['Kyoto', 1989, 180, 'B'], dtype=object)

また、以下のような使い方もできるが

df[1:4] 
出身都道府県 生年 身長 血液型
Bさん Tochigi 1993 156 O
Cさん Hokkaido 2000 162 AB
Dさん Kyoto 1989 180 B

df[1]といった使い方は出来ず、KeyErrorが発生する、

df[1]
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
File ~/venv/lib/python3.12/site-packages/pandas/core/indexes/base.py:3641, in Index.get_loc(self, key)
   3640 try:
-> 3641     return self._engine.get_loc(casted_key)
   3642 except KeyError as err:

File pandas/_libs/index.pyx:168, in pandas._libs.index.IndexEngine.get_loc()

File pandas/_libs/index.pyx:176, in pandas._libs.index.IndexEngine.get_loc()

File pandas/_libs/index.pyx:583, in pandas._libs.index.StringObjectEngine._check_type()

KeyError: 1

The above exception was the direct cause of the following exception:

KeyError                                  Traceback (most recent call last)
Cell In[27], line 1
----> 1 df[1]

File ~/venv/lib/python3.12/site-packages/pandas/core/frame.py:4378, in DataFrame.__getitem__(self, key)
   4376 if self.columns.nlevels > 1:
   4377     return self._getitem_multilevel(key)
-> 4378 indexer = self.columns.get_loc(key)
   4379 if is_integer(indexer):
   4380     indexer = [indexer]

File ~/venv/lib/python3.12/site-packages/pandas/core/indexes/base.py:3648, in Index.get_loc(self, key)
   3643     if isinstance(casted_key, slice) or (
   3644         isinstance(casted_key, abc.Iterable)
   3645         and any(isinstance(x, slice) for x in casted_key)
   3646     ):
   3647         raise InvalidIndexError(key) from err
-> 3648     raise KeyError(key) from err
   3649 except TypeError:
   3650     # If we have a listlike key, _check_indexing_error will raise
   3651     #  InvalidIndexError. Otherwise we fall through and re-raise
   3652     #  the TypeError.
   3653     self._check_indexing_error(key)

KeyError: 1

より複雑な行・列の抽出#

上にならって、2000年より前に生まれた人だけを抽出し

df[ df["生年"] < 2000 ]

さらにこのうち身長が170cm以上の人だけがほしければ

df[(df["生年"] < 2000) & (df["身長"]>170)]
出身都道府県 生年 身長 血液型
Aさん Tokyo 1998 172 A
Dさん Kyoto 1989 180 B

などとすればよい。複数条件の場合は、条件を()で囲む必要があることに注意しよう。

他にもiloc,locなどを用いれば、特定の行・列を抽出することができる

  • ilocは番号の指定のみに対応

  • locは名前(列名・行明)のみ

欲しい要素の数値もしくは項目名のリストを行・列のそれぞれについて指定してやればよい。

df.iloc[[0], [0]] #0行目,0列目
出身都道府県
Aさん Tokyo
#スライスで指定することもできる
df.iloc[1:4, :3] #1-3行目かつ0-2列目 (スライスの終点は含まれないことに注意)
#スライスの場合は、 1:4が[1,2,3]と同じ働きをするので、括弧[]はいらない
出身都道府県 生年 身長
Bさん Tochigi 1993 156
Cさん Hokkaido 2000 162
Dさん Kyoto 1989 180

locを使う場合は、indexの代わりに項目名で指定する。

df.loc[["Aさん","Cさん"],["出身都道府県","身長"]] 
出身都道府県 身長
Aさん Tokyo 172
Cさん Hokkaido 162

スライス的に指定することもできる

df.loc["Bさん":"Dさん","出身都道府県":"生年"]
出身都道府県 生年
Bさん Tochigi 1993
Cさん Hokkaido 2000
Dさん Kyoto 1989

といった具合。

locを使う場合、1:4や[1,2,3,4]はindexのスライスではなく、
項目名を意味し、Eさんのデータも含まれている事がわかる。

Webページにある表をDataFrameとして取得する#

pandas内のread_html関数を用いれば、
Webページの中にある表をDataFrame形式で取得することもできます。

以下では例としてWikipediaのノーベル物理学賞のページにある、受賞者一覧を取得してみましょう

url = "https://ja.wikipedia.org/wiki/%E3%83%8E%E3%83%BC%E3%83%99%E3%83%AB%E7%89%A9%E7%90%86%E5%AD%A6%E8%B3%9E%E5%8F%97%E8%B3%9E%E8%80%85%E3%81%AE%E4%B8%80%E8%A6%A7"
tables = pd.read_html(url, storage_options = {'User-Agent': 'Mozilla/5.0'})

表の数を数えてみると…

print(len(tables))
15

ページ内に、たくさんの表があることがわかります。(wikipediaのテンプレート等も含まれている)

たとえば、前から3番目の表を見てみると…

df = tables[3]
df
年度 受賞者名 受賞者名.1 国籍 受賞理由[6]・原著ないし関連論文
0 1930年 NaN チャンドラセカール・ラマン Sir Chandrasekhara Venkata Raman イギリス領インド帝国 光散乱に関する研究と彼に因んで命名されたラマン効果の発見 Nature: 121 (1928...
1 1931年 受賞者なし 受賞者なし NaN 賞金はノーベル物理学賞の基金に割り当てられた
2 1932年 NaN ヴェルナー・ハイゼンベルク Werner Karl Heisenberg ドイツ国 量子力学の創始[注 17]ならびにその応用、特に同素異形の水素[注 18]の発見 Z. Ph...
3 1933年 NaN エルヴィン・シュレーディンガー Erwin Schrödinger オーストリア 原子論の新しく有効な形式の発見[注 19] Phys. Rev.: 28 (1926) 10...
4 1933年 NaN ポール・ディラック Paul Adrien Maurice Dirac イギリス 原子論の新しく有効な形式の発見[注 19] Phys. Rev.: 28 (1926) 10...
5 1934年 受賞者なし 受賞者なし NaN 賞金の3分の1はノーベル財団の基金に、残り3分の2はノーベル物理学賞の基金に割り当てられた
6 1935年 NaN ジェームズ・チャドウィック James Chadwick イギリス 中性子の発見 Nature: 129 (1932) 312
7 1936年 NaN ヴィクトール・フランツ・ヘス Victor Franz Hess オーストリア 宇宙線の発見 Phys. Z.: 13 (1912) 1084-1091
8 1936年 NaN カール・デイヴィッド・アンダーソン Carl David Anderson アメリカ合衆国 陽電子の発見 Phys. Rev.: 43 (1933) 491-498 Phys. Rev...
9 1937年 NaN クリントン・デイヴィソン Clinton Joseph Davisson アメリカ合衆国 結晶による電子線回折現象の発見
10 1937年 NaN ジョージ・パジェット・トムソン George Paget Thomson イギリス 結晶による電子線回折現象の発見
11 1938年 NaN エンリコ・フェルミ Enrico Fermi イタリア王国 中性子放射による新放射性元素の存在証明および関連して熱中性子による原子核反応の発見 Z. f...
12 1939年 NaN アーネスト・ローレンス Ernest Orlando Lawrence アメリカ合衆国 サイクロトロンの発明・開発およびその成果、特に人工放射性元素

Pandasでcsv/Excelファイルを読み込む#

csvファイルの読み込み#

pandasには、csvを読み込むための関数read_csvが用意されていて、ファイルパスを指定する他に、URLを指定して開く事ができる。

教育用標準データセットの一つであるSSDSE-B(県別推移)を読み込んでみよう。

下を実行すると…実はエラーとなる。

pd.read_csv("https://www.nstac.go.jp/sys/files/SSDSE-B-2025.csv", storage_options = {'User-Agent': 'Mozilla/5.0'})
---------------------------------------------------------------------------
UnicodeDecodeError                        Traceback (most recent call last)
Cell In[36], line 1
----> 1 pd.read_csv("https://www.nstac.go.jp/sys/files/SSDSE-B-2025.csv", storage_options = {'User-Agent': 'Mozilla/5.0'})

File ~/venv/lib/python3.12/site-packages/pandas/io/parsers/readers.py:873, in read_csv(filepath_or_buffer, sep, delimiter, header, names, index_col, usecols, dtype, engine, converters, true_values, false_values, skipinitialspace, skiprows, skipfooter, nrows, na_values, keep_default_na, na_filter, skip_blank_lines, parse_dates, date_format, dayfirst, cache_dates, iterator, chunksize, compression, thousands, decimal, lineterminator, quotechar, quoting, doublequote, escapechar, comment, encoding, encoding_errors, dialect, on_bad_lines, low_memory, memory_map, float_precision, storage_options, dtype_backend)
    861 kwds_defaults = _refine_defaults_read(
    862     dialect,
    863     delimiter,
   (...)    869     dtype_backend=dtype_backend,
    870 )
    871 kwds.update(kwds_defaults)
--> 873 return _read(filepath_or_buffer, kwds)

File ~/venv/lib/python3.12/site-packages/pandas/io/parsers/readers.py:300, in _read(filepath_or_buffer, kwds)
    297 _validate_names(kwds.get("names", None))
    299 # Create the parser.
--> 300 parser = TextFileReader(filepath_or_buffer, **kwds)
    302 if chunksize or iterator:
    303     return parser

File ~/venv/lib/python3.12/site-packages/pandas/io/parsers/readers.py:1645, in TextFileReader.__init__(self, f, engine, **kwds)
   1642     self.options["has_index_names"] = kwds["has_index_names"]
   1644 self.handles: IOHandles | None = None
-> 1645 self._engine = self._make_engine(f, self.engine)

File ~/venv/lib/python3.12/site-packages/pandas/io/parsers/readers.py:1922, in TextFileReader._make_engine(self, f, engine)
   1919     raise ValueError(msg)
   1921 try:
-> 1922     return mapping[engine](f, **self.options)
   1923 except Exception:
   1924     if self.handles is not None:

File ~/venv/lib/python3.12/site-packages/pandas/io/parsers/c_parser_wrapper.py:95, in CParserWrapper.__init__(self, src, **kwds)
     92 if kwds["dtype_backend"] == "pyarrow":
     93     # Fail here loudly instead of in cython after reading
     94     import_optional_dependency("pyarrow")
---> 95 self._reader = parsers.TextReader(src, **kwds)
     97 self.unnamed_cols = self._reader.unnamed_cols
     99 passed_names = self.names is None

File pandas/_libs/parsers.pyx:568, in pandas._libs.parsers.TextReader.__cinit__()

File pandas/_libs/parsers.pyx:657, in pandas._libs.parsers.TextReader._get_header()

File pandas/_libs/parsers.pyx:868, in pandas._libs.parsers.TextReader._tokenize_rows()

File pandas/_libs/parsers.pyx:885, in pandas._libs.parsers.TextReader._check_tokenize_status()

File pandas/_libs/parsers.pyx:2076, in pandas._libs.parsers.raise_parser_error()

File <frozen codecs>:322, in decode(self, input, final)

UnicodeDecodeError: 'utf-8' codec can't decode byte 0x94 in position 748: invalid start byte

その原因は、ファイルの文字コードがShift-JISであるため。 デフォルトのutf-8以外で作成されたファイルを読み込む場合、エンコーディングを指定する必要がある。

“shift_jis”等としたいところだが、最近のShift-JISに対応するエンコーディングの指示は”cp932”である。

df = pd.read_csv("https://www.nstac.go.jp/sys/files/SSDSE-B-2025.csv", encoding="cp932", storage_options = {'User-Agent': 'Mozilla/5.0'})
df
SSDSE-B-2025 Code Prefecture A1101 A110101 A110102 A1102 A110201 A110202 A1301 ... L322101 L322102 L322103 L322104 L322105 L322106 L322107 L322108 L322109 L322110
0 年度 地域コード 都道府県 総人口 総人口(男) 総人口(女) 日本人人口 日本人人口(男) 日本人人口(女) 15歳未満人口 ... 食料費(二人以上の世帯) 住居費(二人以上の世帯) 光熱・水道費(二人以上の世帯) 家具・家事用品費(二人以上の世帯) 被服及び履物費(二人以上の世帯) 保健医療費(二人以上の世帯) 交通・通信費(二人以上の世帯) 教育費(二人以上の世帯) 教養娯楽費(二人以上の世帯) その他の消費支出(二人以上の世帯)
1 2022 R01000 北海道 5140000 2427000 2714000 5098000 2407000 2692000 530000 ... 73037 24873 30010 10156 8928 12080 35403 9551 27234 46466
2 2021 R01000 北海道 5183000 2446000 2737000 5147000 2429000 2717000 544000 ... 71448 22013 26676 9912 8816 13788 30483 9913 23762 51583
3 2020 R01000 北海道 5224614 2465088 2759526 5151366 2429697 2721669 555804 ... 77680 27305 27309 12255 9227 14251 41407 9394 26539 56316
4 2019 R01000 北海道 5259000 2480000 2780000 5223000 2464000 2759000 565000 ... 72912 20862 26332 9895 10466 16466 42277 8848 29335 57289
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
560 2015 R47000 沖縄県 1433566 704619 728947 1410487 692392 718095 247206 ... 61078 20973 20365 9379 7912 9360 31706 8522 19215 45262
561 2014 R47000 沖縄県 1426000 700000 725000 1416000 695000 721000 249000 ... 56734 20998 20722 7509 6622 9531 32302 9016 18570 43864
562 2013 R47000 沖縄県 1419000 697000 722000 1410000 692000 718000 249000 ... 57278 23557 20499 7335 7398 9281 33976 9714 20199 50418
563 2012 R47000 沖縄県 1411000 693000 719000 1403000 688000 715000 248000 ... 55499 23731 19756 7353 6856 9948 27855 7769 19324 49890
564 2011 R47000 沖縄県 1402000 688000 714000 1395000 684000 711000 247000 ... 53193 23454 20645 6136 6855 9775 26806 7489 18818 48762

565 rows × 112 columns

今の場合ファイルの(0から数えて)1行目にヘッダ(列名)にしたい情報があるのでheaderオプションを指定する。

url = "https://www.nstac.go.jp/sys/files/SSDSE-B-2025.csv"
df = pd.read_csv(url, encoding="cp932", header=1, storage_options = {'User-Agent': 'Mozilla/5.0'})
df
年度 地域コード 都道府県 総人口 総人口(男) 総人口(女) 日本人人口 日本人人口(男) 日本人人口(女) 15歳未満人口 ... 食料費(二人以上の世帯) 住居費(二人以上の世帯) 光熱・水道費(二人以上の世帯) 家具・家事用品費(二人以上の世帯) 被服及び履物費(二人以上の世帯) 保健医療費(二人以上の世帯) 交通・通信費(二人以上の世帯) 教育費(二人以上の世帯) 教養娯楽費(二人以上の世帯) その他の消費支出(二人以上の世帯)
0 2022 R01000 北海道 5140000 2427000 2714000 5098000 2407000 2692000 530000 ... 73037 24873 30010 10156 8928 12080 35403 9551 27234 46466
1 2021 R01000 北海道 5183000 2446000 2737000 5147000 2429000 2717000 544000 ... 71448 22013 26676 9912 8816 13788 30483 9913 23762 51583
2 2020 R01000 北海道 5224614 2465088 2759526 5151366 2429697 2721669 555804 ... 77680 27305 27309 12255 9227 14251 41407 9394 26539 56316
3 2019 R01000 北海道 5259000 2480000 2780000 5223000 2464000 2759000 565000 ... 72912 20862 26332 9895 10466 16466 42277 8848 29335 57289
4 2018 R01000 北海道 5293000 2495000 2798000 5262000 2482000 2780000 577000 ... 69044 19089 27012 8845 11517 11437 39308 10825 26991 56984
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
559 2015 R47000 沖縄県 1433566 704619 728947 1410487 692392 718095 247206 ... 61078 20973 20365 9379 7912 9360 31706 8522 19215 45262
560 2014 R47000 沖縄県 1426000 700000 725000 1416000 695000 721000 249000 ... 56734 20998 20722 7509 6622 9531 32302 9016 18570 43864
561 2013 R47000 沖縄県 1419000 697000 722000 1410000 692000 718000 249000 ... 57278 23557 20499 7335 7398 9281 33976 9714 20199 50418
562 2012 R47000 沖縄県 1411000 693000 719000 1403000 688000 715000 248000 ... 55499 23731 19756 7353 6856 9948 27855 7769 19324 49890
563 2011 R47000 沖縄県 1402000 688000 714000 1395000 684000 711000 247000 ... 53193 23454 20645 6136 6855 9775 26806 7489 18818 48762

564 rows × 112 columns

都道府県の列から、都道府県の名前を取り出してみよう。

ある行以降はNaNになっているので、それを除去する。

※こちらは古い記述で、2025年現在のデータでは、NaNが発生しないよう修正されています。ただし、ファイルに値なしが含まれている場合もあるので、記述を残しておきます。

df = pd.read_csv(url, encoding="cp932", header=1, storage_options = {'User-Agent': 'Mozilla/5.0'})
df = df.dropna()
df
年度 地域コード 都道府県 総人口 総人口(男) 総人口(女) 日本人人口 日本人人口(男) 日本人人口(女) 15歳未満人口 ... 食料費(二人以上の世帯) 住居費(二人以上の世帯) 光熱・水道費(二人以上の世帯) 家具・家事用品費(二人以上の世帯) 被服及び履物費(二人以上の世帯) 保健医療費(二人以上の世帯) 交通・通信費(二人以上の世帯) 教育費(二人以上の世帯) 教養娯楽費(二人以上の世帯) その他の消費支出(二人以上の世帯)
0 2022 R01000 北海道 5140000 2427000 2714000 5098000 2407000 2692000 530000 ... 73037 24873 30010 10156 8928 12080 35403 9551 27234 46466
1 2021 R01000 北海道 5183000 2446000 2737000 5147000 2429000 2717000 544000 ... 71448 22013 26676 9912 8816 13788 30483 9913 23762 51583
2 2020 R01000 北海道 5224614 2465088 2759526 5151366 2429697 2721669 555804 ... 77680 27305 27309 12255 9227 14251 41407 9394 26539 56316
3 2019 R01000 北海道 5259000 2480000 2780000 5223000 2464000 2759000 565000 ... 72912 20862 26332 9895 10466 16466 42277 8848 29335 57289
4 2018 R01000 北海道 5293000 2495000 2798000 5262000 2482000 2780000 577000 ... 69044 19089 27012 8845 11517 11437 39308 10825 26991 56984
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
559 2015 R47000 沖縄県 1433566 704619 728947 1410487 692392 718095 247206 ... 61078 20973 20365 9379 7912 9360 31706 8522 19215 45262
560 2014 R47000 沖縄県 1426000 700000 725000 1416000 695000 721000 249000 ... 56734 20998 20722 7509 6622 9531 32302 9016 18570 43864
561 2013 R47000 沖縄県 1419000 697000 722000 1410000 692000 718000 249000 ... 57278 23557 20499 7335 7398 9281 33976 9714 20199 50418
562 2012 R47000 沖縄県 1411000 693000 719000 1403000 688000 715000 248000 ... 55499 23731 19756 7353 6856 9948 27855 7769 19324 49890
563 2011 R47000 沖縄県 1402000 688000 714000 1395000 684000 711000 247000 ... 53193 23454 20645 6136 6855 9775 26806 7489 18818 48762

564 rows × 112 columns

あるいは、特定の列の特定の行がNaNかどうかを調べて除外してみると

df = pd.read_csv(url, encoding="cp932", header=1, storage_options = {'User-Agent': 'Mozilla/5.0'})
df = df.dropna(subset=['都道府県'])
df
年度 地域コード 都道府県 総人口 総人口(男) 総人口(女) 日本人人口 日本人人口(男) 日本人人口(女) 15歳未満人口 ... 食料費(二人以上の世帯) 住居費(二人以上の世帯) 光熱・水道費(二人以上の世帯) 家具・家事用品費(二人以上の世帯) 被服及び履物費(二人以上の世帯) 保健医療費(二人以上の世帯) 交通・通信費(二人以上の世帯) 教育費(二人以上の世帯) 教養娯楽費(二人以上の世帯) その他の消費支出(二人以上の世帯)
0 2022 R01000 北海道 5140000 2427000 2714000 5098000 2407000 2692000 530000 ... 73037 24873 30010 10156 8928 12080 35403 9551 27234 46466
1 2021 R01000 北海道 5183000 2446000 2737000 5147000 2429000 2717000 544000 ... 71448 22013 26676 9912 8816 13788 30483 9913 23762 51583
2 2020 R01000 北海道 5224614 2465088 2759526 5151366 2429697 2721669 555804 ... 77680 27305 27309 12255 9227 14251 41407 9394 26539 56316
3 2019 R01000 北海道 5259000 2480000 2780000 5223000 2464000 2759000 565000 ... 72912 20862 26332 9895 10466 16466 42277 8848 29335 57289
4 2018 R01000 北海道 5293000 2495000 2798000 5262000 2482000 2780000 577000 ... 69044 19089 27012 8845 11517 11437 39308 10825 26991 56984
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
559 2015 R47000 沖縄県 1433566 704619 728947 1410487 692392 718095 247206 ... 61078 20973 20365 9379 7912 9360 31706 8522 19215 45262
560 2014 R47000 沖縄県 1426000 700000 725000 1416000 695000 721000 249000 ... 56734 20998 20722 7509 6622 9531 32302 9016 18570 43864
561 2013 R47000 沖縄県 1419000 697000 722000 1410000 692000 718000 249000 ... 57278 23557 20499 7335 7398 9281 33976 9714 20199 50418
562 2012 R47000 沖縄県 1411000 693000 719000 1403000 688000 715000 248000 ... 55499 23731 19756 7353 6856 9948 27855 7769 19324 49890
563 2011 R47000 沖縄県 1402000 688000 714000 1395000 684000 711000 247000 ... 53193 23454 20645 6136 6855 9775 26806 7489 18818 48762

564 rows × 112 columns

県名を取得したければ例えば

prefectures = list(df["都道府県"].unique())
print(prefectures)
['北海道', '青森県', '岩手県', '宮城県', '秋田県', '山形県', '福島県', '茨城県', '栃木県', '群馬県', '埼玉県', '千葉県', '東京都', '神奈川県', '新潟県', '富山県', '石川県', '福井県', '山梨県', '長野県', '岐阜県', '静岡県', '愛知県', '三重県', '滋賀県', '京都府', '大阪府', '兵庫県', '奈良県', '和歌山県', '鳥取県', '島根県', '岡山県', '広島県', '山口県', '徳島県', '香川県', '愛媛県', '高知県', '福岡県', '佐賀県', '長崎県', '熊本県', '大分県', '宮崎県', '鹿児島県', '沖縄県']

NaNの判定は少しトリッキーで、単純な二項演算子で判定しようとすると直感と異なる振る舞いになる。

print("nan同士を==で評価(しているつもり)", float('nan') == float('nan'))
nan同士を==で評価(しているつもり) False

さきほどのデータの例で、都道府県列からNaNでないものを取っている (※2025年以降のデータでは、NaNが発生しないよう修正されています)

df = pd.read_csv(url, encoding="cp932", header=1, storage_options = {'User-Agent': 'Mozilla/5.0'})
df[df["都道府県"] != float('nan') ]["都道府県"].unique()
<StringArray>
[ '北海道',  '青森県',  '岩手県',  '宮城県',  '秋田県',  '山形県',  '福島県',  '茨城県',  '栃木県',
  '群馬県',  '埼玉県',  '千葉県',  '東京都', '神奈川県',  '新潟県',  '富山県',  '石川県',  '福井県',
  '山梨県',  '長野県',  '岐阜県',  '静岡県',  '愛知県',  '三重県',  '滋賀県',  '京都府',  '大阪府',
  '兵庫県',  '奈良県', '和歌山県',  '鳥取県',  '島根県',  '岡山県',  '広島県',  '山口県',  '徳島県',
  '香川県',  '愛媛県',  '高知県',  '福岡県',  '佐賀県',  '長崎県',  '熊本県',  '大分県',  '宮崎県',
 '鹿児島県',  '沖縄県']
Length: 47, dtype: str

Nanに対して定義された関数やメソッドを用いる必要がある。

Excelファイルの読み込み#

PandasにはEXcelFileread_excelという関数が用意されていて、多数のシートを含むようなエクセルファイルを開くことも出来る。

今まではGoogle Driveにいれたファイルを読み出していたが、
Webから直接xlsxファイルを読み込んでみよう。

url = "https://www.mext.go.jp/content/20201225-mxt_kagsei-mext_01110_012.xlsx"
input_file = pd.ExcelFile(url)

ブック内のシートの一覧は以下のように取得できる。

sheet_names = input_file.sheet_names
print("pandas: シート名",sheet_names)
pandas: シート名 ['表全体', '1穀類', '2いも及びでん粉類', '3砂糖及び甘味類', '4豆類', '5種実類', '6野菜類', '7果実類', '8きのこ類', '9藻類', '10魚介類', '11肉類', '12鶏卵', '13乳類', '14油脂類', '15菓子類', '16し好飲料', '17調味料及び香辛料', '18調理済み流通食品類']

シートを指定するのは、インデックスかシート名の文字列で行う。

“1 穀類”を使うことにして、
pandasにあるread_excel関数を使ってみよう。
read_excel関数の最初の引数にはパスの他に、urlも取れる。

df = pd.read_excel(url,sheet_name="1穀類")
df
Unnamed: 0 Unnamed: 1 Unnamed: 2 Unnamed: 3 Unnamed: 4 Unnamed: 5 Unnamed: 6 Unnamed: 7 Unnamed: 8 Unnamed: 9 ... Unnamed: 52 Unnamed: 53 Unnamed: 54 Unnamed: 55 Unnamed: 56 Unnamed: 57 Unnamed: 58 Unnamed: 59 Unnamed: 60 更新日:2021年12月28日
0 NaN 食 品 番 号 索 引 番 号 可  食  部   100  g  当  た  り NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN 備  考
1 NaN NaN NaN 食 品 名 廃 棄 率 エネルギー NaN 水 分 たんぱく質 NaN ... NaN NaN NaN NaN NaN NaN NaN アルコール 食塩相当量 NaN
2 NaN NaN NaN NaN NaN NaN NaN NaN アミノ酸組成による\nたんぱく質 たんぱく質 ... ナイアシン当量 ビ\nタ\nミ\nン\nB6 ビ\nタ\nミ\nン\nB12 葉 酸 パントテン酸 ビ オ チ ン ビタミンC NaN NaN NaN
3 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
4 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
211 1.0 01139 201 ひえ 精白粒 0 1534 361 12.9 8.4 9.4 ... 2.3 0.17 (0) 14 1.50 3.6 0 - 0 歩留り: 55~60 %
212 1.0 01140 202 もろこし 玄穀 0 1454 344 12.0 (9.0) 10.3 ... (8.0) 0.31 (0) 54 1.42 15.0 (0) - 0 別名: こうりゃん、ソルガム、たかきび、マイロ
213 1.0 01141 203 もろこし 精白粒 0 1473 348 12.5 (8.0) 9.5 ... (5.0) 0.24 (0) 29 0.66 - (0) - 0 別名: こうりゃん、ソルガム、たかきび、マイロ\n歩留り: 70~80 %
214 1.0 01142 204 ライむぎ 全粒粉 0 1342 317 12.5 10.8 12.7 ... 4.2 0.22 (0) 65 0.87 9.5 0 - 0 別名:黒麦(くろむぎ)
215 1.0 01143 205 ライむぎ ライ麦粉 0 1368 324 13.5 7.8 8.5 ... 2.6 0.10 (0) 34 0.63 - (0) - 0 別名:黒麦(くろむぎ)\n歩留り: 65~75 %

216 rows × 62 columns

同じものが得られている。

Excelファイルの読み込みに関する補足#

pandas内部ではExcelFileというクラスがExcelファイルを扱うために用意されている。

Excelファイルが単一のシートしかない場合や、上でやったようにExcelFile化してシート名を既に知っている場合は、read_excel関数で直接読み込むことができ、DataFrameとして取得できる。

ファイルや使用環境によっては、読み込む際にエラーが出ることがある。

その場合、openpyxlというライブラリをインストールすることで解決することがある。 以下のようにしてインストールし、read_excelのオプションとしてengine="openpyxl"を指定するとよい。

!pip install openpyxl
df = pd.read_excel('filepath.xlsx',engine="openpyxl")

データの整形#

次に、今取得したデータフレームのままでは少々扱い辛いので”整形”を考える。
というのも前から4行ほど表示してみると…

df[0:4] 
Unnamed: 0 Unnamed: 1 Unnamed: 2 Unnamed: 3 Unnamed: 4 Unnamed: 5 Unnamed: 6 Unnamed: 7 Unnamed: 8 Unnamed: 9 ... Unnamed: 52 Unnamed: 53 Unnamed: 54 Unnamed: 55 Unnamed: 56 Unnamed: 57 Unnamed: 58 Unnamed: 59 Unnamed: 60 更新日:2021年12月28日
0 NaN 食 品 番 号 索 引 番 号 可  食  部   100  g  当  た  り NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN 備  考
1 NaN NaN NaN 食 品 名 廃 棄 率 エネルギー NaN 水 分 たんぱく質 NaN ... NaN NaN NaN NaN NaN NaN NaN アルコール 食塩相当量 NaN
2 NaN NaN NaN NaN NaN NaN NaN NaN アミノ酸組成による\nたんぱく質 たんぱく質 ... ナイアシン当量 ビ\nタ\nミ\nン\nB6 ビ\nタ\nミ\nン\nB12 葉 酸 パントテン酸 ビ オ チ ン ビタミンC NaN NaN NaN
3 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN

4 rows × 62 columns

最初の4行ほどに栄養素等の情報が入っているのだが、
セルが結合されたりしているため、所々にNaNが入っていたりして見辛い。

(碁盤目の構造を破壊してしまうため「セルの結合」は機械的な処理と
やや相性が悪く、プログラミングを用いたデータ分析では嫌われる)

各省庁の公開データのフォーマットの統一化は今後に期待することにして…
まず以下の項目に該当する列だけを抽出する事を考える。

targets = ["食品名", "エネルギー","たんぱく質", "脂質", "炭水化物"]

該当するデータがどの行・列に格納されているかをコードで指定するのは、
前述のファイル構造の事情からやや面倒くさい。

以下では、その場しのぎ的ではあるが、
興味のある量が何番目かを指定してまとめてみることにしよう。

そのために、1-2行目の要素を表示してみよう。

#1-2行目(エクセルだと2行目)の要素から
    #半角空白, 全角空白(\u3000)や改行コード\nを取り除いたリストを作って表示してみる

for idx in range(1,3):
    tmp = df.iloc[idx].values
    tlist = list(map( lambda s: str(s).replace("\u3000","").replace("\n","").replace(" ",""),tmp))
    print(tlist)
['nan', 'nan', 'nan', '食品名', '廃棄率', 'エネルギー', 'nan', '水分', 'たんぱく質', 'nan', '脂質', 'nan', 'nan', '炭水化物', 'nan', 'nan', 'nan', 'nan', 'nan', 'nan', 'nan', '有機酸', '灰分', '無機質', 'nan', 'nan', 'nan', 'nan', 'nan', 'nan', 'nan', 'nan', 'nan', '無機質', 'nan', 'nan', 'nan', 'ビタミン', 'nan', 'nan', 'nan', 'nan', 'nan', 'nan', 'nan', 'nan', 'nan', 'nan', 'nan', 'nan', 'nan', 'nan', 'nan', 'nan', 'nan', 'nan', 'nan', 'nan', 'nan', 'アルコール', '食塩相当量', 'nan']
['nan', 'nan', 'nan', 'nan', 'nan', 'nan', 'nan', 'nan', 'アミノ酸組成によるたんぱく質', 'たんぱく質', '脂肪酸のトリアシルグリセロール当量', 'コレステロール', '脂質', '利用可能炭水化物', 'nan', 'nan', 'nan', 'nan', '食物繊維総量', '糖アルコール', '炭水化物', 'nan', 'nan', 'ナトリウム', 'カリウム', 'カルシウム', 'マグネシウム', 'リン', '鉄', '亜鉛', '銅', 'マンガン', 'nan', 'ヨウ素', 'セレン', 'クロム', 'モリブデン', 'ビタミンA', 'nan', 'nan', 'nan', 'nan', 'nan', 'ビタミンD', 'ビタミンE', 'nan', 'nan', 'nan', 'ビタミンK', 'ビタミンB1', 'ビタミンB2', 'ナイアシン', 'ナイアシン当量', 'ビタミンB6', 'ビタミンB12', '葉酸', 'パントテン酸', 'ビオチン', 'ビタミンC', 'nan', 'nan', 'nan']

セルの結合により、興味のあるデータがどの列に記述されているかは注意が必要。

実際、[エネルギー]という文字列は1行目の6列目(それぞれインデックスでいうと0,5)で取得できるが、
kJ単位になっていて、kcal単位でほしければ、7列目に格納された値が必要になる。

また、エクセルファイルを見るとわかるように、たんぱく質・脂質・炭水化物はさらに細分化されており、
O列R列など、細かい列の分割が挿入されている. ~~これは大変困る~~

単純にたんぱく質・脂質・炭水化物と表記されている列のインデックスはそれぞれ9,12,20となる。
食品名が格納されている列(3)、エネルギー[kJ単位] (6)と合わせて確認してみよう。

targets = [3,6,9,12,20]
df.iloc[:,targets]
Unnamed: 3 Unnamed: 6 Unnamed: 9 Unnamed: 12 Unnamed: 20
0 可  食  部   100  g  当  た  り NaN NaN NaN NaN
1 食 品 名 NaN NaN NaN NaN
2 NaN NaN たんぱく質 脂質 炭水化物
3 NaN NaN NaN NaN NaN
4 NaN NaN NaN NaN NaN
... ... ... ... ... ...
211 ひえ 精白粒 361 9.4 3.3 73.2
212 もろこし 玄穀 344 10.3 4.7 71.1
213 もろこし 精白粒 348 9.5 2.6 74.1
214 ライむぎ 全粒粉 317 12.7 2.7 70.7
215 ライむぎ ライ麦粉 324 8.5 1.6 75.8

216 rows × 5 columns

もう少し整形したいので、新しいデータフレームの列を書き換える。

食品名等が記載されているのは10行目以降なので、それを使いcolumnsを指定する。

さらに、食品名に含まれる余分な文字コードも削除しておこう。

ndf = df.iloc[:,targets] 
ndf = ndf.iloc[10:,:]
ndf.columns=["食品名","エネルギー(kcal)","たんぱく質(g)","脂質(g)","炭水化物(g)"]
ndf["食品名"] = ndf["食品名"].str.replace("\u3000"," ") # 食品名の中にある余分な全角空白(\u3000)を半角スペースに置き換える
ndf
食品名 エネルギー(kcal) たんぱく質(g) 脂質(g) 炭水化物(g)
10 成分識別子 ENERC_KCAL PROT- FAT- CHOCDF-
11 アマランサス 玄穀 343 12.7 6.0 64.9
12 あわ 精白粒 346 11.2 4.4 69.7
13 あわ あわもち 210 5.1 1.3 45.3
14 えんばく オートミール 350 13.7 5.7 69.1
... ... ... ... ... ...
211 ひえ 精白粒 361 9.4 3.3 73.2
212 もろこし 玄穀 344 10.3 4.7 71.1
213 もろこし 精白粒 348 9.5 2.6 74.1
214 ライむぎ 全粒粉 317 12.7 2.7 70.7
215 ライむぎ ライ麦粉 324 8.5 1.6 75.8

206 rows × 5 columns

次に、食品名の一覧を取得した後、興味のあるもの(日常的に馴染みのあるもの)だけを
ピックアップしてみよう。

print(list(ndf["食品名"]))
['成分識別子', 'アマランサス 玄穀', 'あわ 精白粒', 'あわ あわもち', 'えんばく オートミール', 'おおむぎ 七分つき押麦', 'おおむぎ 押麦 乾', 'おおむぎ 押麦 めし', 'おおむぎ 米粒麦', 'おおむぎ 大麦めん 乾', 'おおむぎ 大麦めん ゆで', 'おおむぎ 麦こがし', 'キヌア 玄穀', 'きび 精白粒', 'こむぎ [玄穀] 国産 普通', 'こむぎ [玄穀] 輸入 軟質', 'こむぎ [玄穀] 輸入 硬質', 'こむぎ [小麦粉] 薄力粉 1等', 'こむぎ [小麦粉] 薄力粉 2等', 'こむぎ [小麦粉] 中力粉 1等', 'こむぎ [小麦粉] 中力粉 2等', 'こむぎ [小麦粉] 強力粉 1等', 'こむぎ [小麦粉] 強力粉 2等', 'こむぎ [小麦粉] 強力粉 全粒粉', 'こむぎ [小麦粉] プレミックス粉 お好み焼き用', 'こむぎ [小麦粉] プレミックス粉 ホットケーキ用', 'こむぎ [小麦粉] プレミックス粉 から揚げ用', 'こむぎ [小麦粉] プレミックス粉 天ぷら用', 'こむぎ [小麦粉] プレミックス粉 天ぷら用 バッター', 'こむぎ [小麦粉] プレミックス粉 天ぷら用 バッター 揚げ', 'こむぎ [パン類] 角形食パン 食パン', 'こむぎ [パン類] 角形食パン 焼き', 'こむぎ [パン類] 角形食パン 耳を除いたもの', 'こむぎ [パン類] 角形食パン 耳', 'こむぎ [パン類] 食パン リーンタイプ', 'こむぎ [パン類] 食パン リッチタイプ', 'こむぎ [パン類] 山形食パン 食パン', 'こむぎ [パン類] コッペパン', 'こむぎ [パン類] 乾パン', 'こむぎ [パン類] フランスパン', 'こむぎ [パン類] ライ麦パン', 'こむぎ [パン類] 全粒粉パン', 'こむぎ [パン類] ぶどうパン', 'こむぎ [パン類] ロールパン', 'こむぎ [パン類] クロワッサン レギュラータイプ', 'こむぎ [パン類] クロワッサン リッチタイプ', 'こむぎ [パン類] くるみパン', 'こむぎ [パン類] イングリッシュマフィン', 'こむぎ [パン類] ナン', 'こむぎ [パン類] ベーグル', 'こむぎ [うどん・そうめん類] うどん 生', 'こむぎ [うどん・そうめん類] うどん ゆで', 'こむぎ [うどん・そうめん類] うどん 半生うどん', 'こむぎ [うどん・そうめん類] 干しうどん 乾', 'こむぎ [うどん・そうめん類] 干しうどん ゆで', 'こむぎ [うどん・そうめん類] そうめん・ひやむぎ 乾', 'こむぎ [うどん・そうめん類] そうめん・ひやむぎ ゆで', 'こむぎ [うどん・そうめん類] 手延そうめん・手延ひやむぎ 乾', 'こむぎ [うどん・そうめん類] 手延そうめん・手延ひやむぎ ゆで', 'こむぎ [中華めん類] 中華めん 生', 'こむぎ [中華めん類] 中華めん ゆで', 'こむぎ [中華めん類] 半生中華めん ', 'こむぎ [中華めん類] 蒸し中華めん 蒸し中華めん', 'こむぎ [中華めん類] 蒸し中華めん  ソテー', 'こむぎ [中華めん類] 干し中華めん 乾', 'こむぎ [中華めん類] 干し中華めん ゆで', 'こむぎ [中華めん類] 沖縄そば 生', 'こむぎ [中華めん類] 沖縄そば ゆで', 'こむぎ [中華めん類] 干し沖縄そば 乾', 'こむぎ [中華めん類] 干し沖縄そば ゆで', 'こむぎ [即席めん類] 即席中華めん 油揚げ味付け', 'こむぎ [即席めん類] 即席中華めん 油揚げ 乾 (添付調味料等を含むもの)', 'こむぎ [即席めん類] 即席中華めん 油揚げ 調理後全体 (添付調味料等を含むもの)', 'こむぎ [即席めん類] 即席中華めん 油揚げ ゆで (添付調味料等を含まないもの)', 'こむぎ [即席めん類] 即席中華めん 油揚げ 乾 (添付調味料等を含まないもの)', 'こむぎ [即席めん類] 即席中華めん 非油揚げ 乾 (添付調味料等を含むもの)', 'こむぎ [即席めん類] 即席中華めん 非油揚げ 調理後全体 (添付調味料等を含むもの)', 'こむぎ [即席めん類] 即席中華めん 非油揚げ ゆで (添付調味料等を含まないもの)', 'こむぎ [即席めん類] 即席中華めん 非油揚げ 乾 (添付調味料等を含まないもの)', 'こむぎ [即席めん類] 中華スタイル即席カップめん 油揚げ 塩味 乾 (添付調味料等を含むもの)', 'こむぎ [即席めん類] 中華スタイル即席カップめん 油揚げ 塩味 調理後全体 (添付調味料等を含むもの)', 'こむぎ [即席めん類] 中華スタイル即席カップめん 油揚げ 塩味 調理後のめん (スープを残したもの)', 'こむぎ [即席めん類] 中華スタイル即席カップめん 油揚げ しょうゆ味 乾 (添付調味料等を含むもの)', 'こむぎ [即席めん類] 中華スタイル即席カップめん 油揚げ しょうゆ味 調理後全体 (添付調味料等を含むもの)', 'こむぎ [即席めん類] 中華スタイル即席カップめん 油揚げ しょうゆ味 調理後のめん (スープを残したもの)', 'こむぎ [即席めん類] 中華スタイル即席カップめん 油揚げ 焼きそば 乾 (添付調味料等を含むもの)', 'こむぎ [即席めん類] 中華スタイル即席カップめん 油揚げ 焼きそば 調理後全体 (添付調味料等を含むもの)', 'こむぎ [即席めん類] 中華スタイル即席カップめん 非油揚げ 乾 (添付調味料等を含むもの)', 'こむぎ [即席めん類] 中華スタイル即席カップめん 非油揚げ 調理後全体 (添付調味料等を含むもの)', 'こむぎ [即席めん類] 中華スタイル即席カップめん 非油揚げ 調理後のめん (スープを残したもの)', 'こむぎ [即席めん類] 和風スタイル即席カップめん 油揚げ 乾 (添付調味料等を含むもの)', 'こむぎ [即席めん類] 和風スタイル即席カップめん 油揚げ 調理後全体 (添付調味料等を含むもの)', 'こむぎ [即席めん類] 和風スタイル即席カップめん 油揚げ 調理後のめん (スープを残したもの)', 'こむぎ [マカロニ・スパゲッティ類] マカロニ・スパゲッティ 乾', 'こむぎ [マカロニ・スパゲッティ類] マカロニ・スパゲッティ ゆで', 'こむぎ [マカロニ・スパゲッティ類] マカロニ・スパゲッティ ソテー', 'こむぎ [マカロニ・スパゲッティ類] 生パスタ 生', 'こむぎ [ふ類] 生ふ', 'こむぎ [ふ類] 焼きふ 釜焼きふ', 'こむぎ [ふ類] 焼きふ 板ふ', 'こむぎ [ふ類] 焼きふ 車ふ', 'こむぎ [ふ類] 油ふ', 'こむぎ [その他] 小麦はいが', 'こむぎ [その他] 小麦たんぱく 粉末状', 'こむぎ [その他] 小麦たんぱく 粒状', 'こむぎ [その他] 小麦たんぱく ペースト状', 'こむぎ [その他] かやきせんべい', 'こむぎ [その他] ぎょうざの皮 生', 'こむぎ [その他] しゅうまいの皮 生', 'こむぎ [その他] 春巻きの皮 生', 'こむぎ [その他] 春巻きの皮 揚げ', 'こむぎ [その他] ピザ生地', 'こむぎ [その他] ちくわぶ', 'こむぎ [その他] パン粉 生', 'こむぎ [その他] パン粉 半生', 'こむぎ [その他] パン粉 乾燥', 'こむぎ [その他] 冷めん 生', 'こめ [水稲穀粒] 玄米', 'こめ [水稲穀粒] 半つき米', 'こめ [水稲穀粒] 七分つき米', 'こめ [水稲穀粒] 精白米 うるち米', 'こめ [水稲穀粒] 精白米 もち米', 'こめ [水稲穀粒] 精白米 インディカ米', 'こめ [水稲穀粒] はいが精米', 'こめ [水稲穀粒] 発芽玄米', 'こめ [水稲穀粒] 赤米', 'こめ [水稲穀粒] 黒米', 'こめ [水稲めし] 玄米', 'こめ [水稲めし] 半つき米', 'こめ [水稲めし] 七分つき米', 'こめ [水稲めし] 精白米 インディカ米', 'こめ [水稲めし] 精白米 うるち米', 'こめ [水稲めし] 精白米 もち米', 'こめ [水稲めし] はいが精米', 'こめ [水稲めし] 発芽玄米', 'こめ [水稲めし] 赤米', 'こめ [水稲めし] 黒米', 'こめ [水稲軟めし] 精白米', 'こめ [水稲全かゆ] 玄米', 'こめ [水稲全かゆ] 半つき米', 'こめ [水稲全かゆ] 七分つき米', 'こめ [水稲全かゆ] 精白米', 'こめ [水稲五分かゆ] 玄米', 'こめ [水稲五分かゆ] 半つき米', 'こめ [水稲五分かゆ] 七分つき米', 'こめ [水稲五分かゆ] 精白米', 'こめ [水稲おもゆ] 玄米', 'こめ [水稲おもゆ] 半つき米', 'こめ [水稲おもゆ] 七分つき米', 'こめ [水稲おもゆ] 精白米', 'こめ [陸稲穀粒] 玄米', 'こめ [陸稲穀粒] 半つき米', 'こめ [陸稲穀粒] 七分つき米', 'こめ [陸稲穀粒] 精白米', 'こめ [陸稲めし] 玄米', 'こめ [陸稲めし] 半つき米', 'こめ [陸稲めし] 七分つき米', 'こめ [陸稲めし] 精白米', 'こめ [うるち米製品] アルファ化米 一般用', 'こめ [うるち米製品] アルファ化米 学校給食用強化品', 'こめ [うるち米製品] おにぎり', 'こめ [うるち米製品] 焼きおにぎり', 'こめ [うるち米製品] きりたんぽ', 'こめ [うるち米製品] 上新粉', 'こめ [うるち米製品] 玄米粉', 'こめ [うるち米製品] 米粉', 'こめ [うるち米製品] 米粉パン 食パン', 'こめ [うるち米製品] 米粉パン ロールパン', 'こめ [うるち米製品] 米粉パン 小麦グルテン不使用のもの', 'こめ [うるち米製品] 米粉めん', 'こめ [うるち米製品] ビーフン', 'こめ [うるち米製品] ライスペーパー', 'こめ [うるち米製品] 米こうじ', 'こめ [もち米製品] もち', 'こめ [もち米製品] 赤飯', 'こめ [もち米製品] あくまき', 'こめ [もち米製品] 白玉粉', 'こめ [もち米製品] 道明寺粉', 'こめ [その他] 米ぬか', 'そば そば粉 全層粉', 'そば そば粉 内層粉', 'そば そば粉 中層粉', 'そば そば粉 表層粉', 'そば そば米', 'そば そば 生', 'そば そば ゆで', 'そば そば 半生そば', 'そば 干しそば 乾', 'そば 干しそば ゆで', 'とうもろこし 玄穀 黄色種', 'とうもろこし 玄穀 白色種', 'とうもろこし コーンミール 黄色種', 'とうもろこし コーンミール 白色種', 'とうもろこし コーングリッツ 黄色種', 'とうもろこし コーングリッツ 白色種', 'とうもろこし コーンフラワー 黄色種', 'とうもろこし コーンフラワー 白色種', 'とうもろこし ジャイアントコーン フライ 味付け', 'とうもろこし ポップコーン', 'とうもろこし コーンフレーク', 'はとむぎ 精白粒', 'ひえ 精白粒', 'もろこし 玄穀', 'もろこし 精白粒', 'ライむぎ 全粒粉', 'ライむぎ ライ麦粉']

この中から…

  • こむぎ[パン類]食パンリッチタイプ

  • こむぎ[パン類]フランスパン

  • こめ[水稲軟めし]精白米

  • そばそばゆで

  • こむぎ[うどん・そうめん類]うどんゆで

のみに興味があれば

tshokuhin = ["こむぎ [パン類] 食パン リッチタイプ","こむぎ [パン類] フランスパン","こめ [水稲軟めし] 精白米", "そば そば ゆで", "こむぎ [うどん・そうめん類] うどん ゆで"]
ndf[ ndf["食品名"].isin(tshokuhin)]
食品名 エネルギー(kcal) たんぱく質(g) 脂質(g) 炭水化物(g)
45 こむぎ [パン類] 食パン リッチタイプ 256 (7.8) (6.0) (45.6)
49 こむぎ [パン類] フランスパン 289 9.4 1.3 57.5
61 こむぎ [うどん・そうめん類] うどん ゆで 95 2.6 0.4 21.6
147 こめ [水稲軟めし] 精白米 113 (1.8) (0.3) (26.4)
195 そば そば ゆで 130 4.8 1.0 26.0

などとする。

‘6野菜類’でも同様に…

df6 = pd.read_excel(url,sheet_name="6野菜類")
df6.iloc[:,[3,6,9,12,20]]
ndf6 = df6.iloc[:,[3,6,9,12,20]] 
ndf6 = ndf6.iloc[10:,:]
ndf6.columns=["食品名","エネルギー(kcal)","たんぱく質(g)","脂質(g)","炭水化物(g)"]
ndf6["食品名"] = ndf6["食品名"].str.replace("\u3000"," ") 
ndf6
食品名 エネルギー(kcal) たんぱく質(g) 脂質(g) 炭水化物(g)
10 成分識別子 ENERC_KCAL PROT- FAT- CHOCDF-
11 アーティチョーク 花らい 生 39 2.3 0.2 11.3
12 アーティチョーク 花らい ゆで 35 2.1 0.1 10.8
13 あさつき 葉 生 34 4.2 0.3 5.6
14 あさつき 葉 ゆで 41 4.2 0.3 7.3
... ... ... ... ... ...
407 (その他) ミックスベジタブル 冷凍 67 3.0 0.7 15.1
408 (その他) ミックスベジタブル 冷凍 ゆで 65 3.1 0.8 14.6
409 (その他) ミックスベジタブル 冷凍 油いため 108 3.3 4.9 15.7
410 (その他) 野菜ミックスジュース 通常タイプ 21 0.8 0.1 4.7
411 (その他) 野菜ミックスジュース 濃縮タイプ 36 1.0 0.3 7.8

402 rows × 5 columns

特定のキーワードを含むものを全て取得して、
食品名を細かく指定したり、対応する行番号のインデックスを取得できたりする

kyabetu = ndf6[ndf6["食品名"].str.contains('キャベツ')]
kyabetu
食品名 エネルギー(kcal) たんぱく質(g) 脂質(g) 炭水化物(g)
81 (キャベツ類) キャベツ 結球葉 生 21 1.3 0.2 5.2
82 (キャベツ類) キャベツ 結球葉 ゆで 19 0.9 0.2 4.6
83 (キャベツ類) キャベツ 結球葉 油いため 78 1.6 6.0 5.9
84 (キャベツ類) グリーンボール 結球葉 生 20 1.4 0.1 4.3
85 (キャベツ類) レッドキャベツ 結球葉 生 30 2.0 0.1 6.7
358 めキャベツ 結球葉 生 52 5.7 0.1 9.9
359 めキャベツ 結球葉 ゆで 51 5.3 0.1 9.8
tomato = ndf6[ndf6["食品名"].str.contains('トマト')]
tomato
食品名 エネルギー(kcal) たんぱく質(g) 脂質(g) 炭水化物(g)
221 (トマト類) 赤色トマト 果実 生 20 0.7 0.1 4.7
222 (トマト類) 赤色ミニトマト 果実 生 30 1.1 0.1 7.2
223 (トマト類) 黄色トマト 果実 生 18 1.1 0.4 3.2
224 (トマト類) ドライトマト 291 14.2 2.1 67.3
225 (トマト類) 加工品 ホール 食塩無添加 21 0.9 0.2 4.4
226 (トマト類) 加工品 トマトジュース 食塩添加 15 0.7 0.1 4.0
227 (トマト類) 加工品 トマトジュース 食塩無添加 18 0.7 0.1 4.0
228 (トマト類) 加工品 ミックスジュース 食塩添加 18 0.6 0 4.3
229 (トマト類) 加工品 ミックスジュース 食塩無添加 18 0.6 0 4.3

DataFrame同士を結合してまとめるなどして扱いやすいデータに整形していく.

縦方向の結合はpandasのconcat(concatenateの略)を使う。

tdf = pd.concat([kyabetu, tomato])
tdf
食品名 エネルギー(kcal) たんぱく質(g) 脂質(g) 炭水化物(g)
81 (キャベツ類) キャベツ 結球葉 生 21 1.3 0.2 5.2
82 (キャベツ類) キャベツ 結球葉 ゆで 19 0.9 0.2 4.6
83 (キャベツ類) キャベツ 結球葉 油いため 78 1.6 6.0 5.9
84 (キャベツ類) グリーンボール 結球葉 生 20 1.4 0.1 4.3
85 (キャベツ類) レッドキャベツ 結球葉 生 30 2.0 0.1 6.7
358 めキャベツ 結球葉 生 52 5.7 0.1 9.9
359 めキャベツ 結球葉 ゆで 51 5.3 0.1 9.8
221 (トマト類) 赤色トマト 果実 生 20 0.7 0.1 4.7
222 (トマト類) 赤色ミニトマト 果実 生 30 1.1 0.1 7.2
223 (トマト類) 黄色トマト 果実 生 18 1.1 0.4 3.2
224 (トマト類) ドライトマト 291 14.2 2.1 67.3
225 (トマト類) 加工品 ホール 食塩無添加 21 0.9 0.2 4.4
226 (トマト類) 加工品 トマトジュース 食塩添加 15 0.7 0.1 4.0
227 (トマト類) 加工品 トマトジュース 食塩無添加 18 0.7 0.1 4.0
228 (トマト類) 加工品 ミックスジュース 食塩添加 18 0.6 0 4.3
229 (トマト類) 加工品 ミックスジュース 食塩無添加 18 0.6 0 4.3

DataFrameのcsv/Excelファイルへの書き出し#

DataFrameオブジェクトは、pandas内の関数・メソッドを用いれば、簡単にcsvやExcelファイルとして書き出すことができる。

実行履歴に残っている適当なDataFrameを、Google Driveにファイルとして書き出してみよう。

from google.colab import drive
drive.mount('/content/drive')

csvとして書き出す場合

適当にパスを指定して、DataFrameオブジェクトにto_csv関数を作用させる。

df.to_csv("/content/drive/MyDrive/pd_write_test.csv")

Excelファイルとして書き出す場合

この場合も同様で、to_excel関数を用いればよい。

df.to_excel("/content/drive/MyDrive/pd_write_test.xlsx")

上記の関数内で書き出しに使う文字コードを指定することもできる。
例: encoding="utf-8_sig", encoding="shift_jis"