ITいろいろ

プログラミングやクラウド、データ解析など、ITにかかわることをいろいろと書いています。

Pandasで必要な列だけを取り出す(複数の条件)

以前のブログで列のフィルタをかける方法を紹介しました。

今回はその応用で、複数の条件でフィルタをかける方法です。

簡単にできるかと思ったら結構ハマってしまったので、、紹介します。

データはこちらを使っています。

コード紹介

# インポート
import pandas as pd
import matplotlib.pyplot as plt

# ファイルの取り込み
df = pd.read_excel("05k2-3.xlsx", skiprows=3, skipfooter=3)

# 人口区分が「総人口」かつ区分が「人口」かつ時間軸コードが2022000606かつ年齢階級が「うち」から始まらないものを抽出
df2 = df[(df['人口区分'] == '総人口') & (df['区分'] == '人口') & (df['時間軸コード'] == 2022000606) & ~(df['年齢階級'].str.startswith('うち'))]

df2

出力結果

少し解説

通常PythonでAND条件、OR条件、NOT条件などを使うときはand, or, notを使います。

例. if ( a == 1 and not(b < 3) )

ただ、Pandasを使う場合は &, |, ~を使います。

これさえ分かっていれば何も難しくはないのですが、知らないとエラーも不親切なため、原因究明が難しいです。

データの傾向をつかむ(uniqueで文字列カテゴリを確認)

データを見るとき、print(df)print(df.head(10))などをしますが、これだとすべてのデータを見ることはできません。

とはいえ全部のデータを見るのは至難の業なので、データ解析にはざっくりと傾向をつかむことが大事です。

今回は文字列データの傾向をつかむことを考えます。

データはこちらを使っています。

コード紹介

# インポート
import pandas as pd

# ファイルの取り込み
df = pd.read_excel("05k2-3.xlsx", skiprows=3, skipfooter=3)

# 人口区分の中にあるデータを確認(重複削除)
df['人口区分'].unique()

出力結果

少し解説

Pandasのunique()関数を使うことで、重複を削除した状態で表示することができます。

これを使えば、「総人口と日本人人口の2つがデータの中にあるのか。じゃあ今回は総人口のデータを使おう」と考えれば、そのデータだけを取り出すdf2 = df[(df['人口区分'] == '総人口')]という次の解析のアクションにつなげられるわけです。

Matplotlibでグラフ化。日本人が詰まる日本語化はこの1行で解決!

今回はMatplotlibでのグラフ化について紹介します。

何回かに分けて説明していこうと思いますが、一番詰まるのが日本語化です。。

よくラベルを全部英語に直して、などされている人もいますが、データの中身にも日本語が入っていたりするので、できれば日本語でそのまま出したいですね。

データはいつものように こちらのデータを使っています。

Matplotlibの日本語化はこの1行

plt.rcParams['font.family'] = "Meiryo"

これだけです。

 コード紹介

# インポート
import pandas as pd
import matplotlib.pyplot as plt

# ファイルの取り込み
df = pd.read_excel("05k2-3.xlsx", skiprows=3, skipfooter=3)

# 日本語化
plt.rcParams['font.family'] = "Meiryo"

#
# グラフ表示
#

# タイトルの設定
plt.title("男性の人口")
# y軸の設定
# plt.ylabel('人口')
# グラフの描画
plt.plot(df.index, df['男'])

# グラフを表示
plt.show()

出力結果

少し解説

今回Meiryoを使いましたが、その他Windows環境ですとMS Gothicなども使えます。(個人的にはタイプしやすいMeiryoを使っています)

注意点としては、私の環境はWindows 10ですので、それ以外のOS(特にMac, Linux)ではまた使えるフォントが異なると思います。

ちなみに、デフォルトのフォントを使うと以下のように、ワーニングとともに文字化けされた結果が表示されます。

Pandasで必要な列だけを取り出す

以前の投稿でフィルタ操作(つまり行の絞り込み)を紹介しましたが、今回は列の操作について紹介します。

データは前回同様、総務省統計局のデータを拝借します。

コード紹介

# インポート
import pandas as pd

# ファイルの取り込み
df = pd.read_excel("05k2-3.xlsx", skiprows=3, skipfooter=3)

# 「時間軸コード」と「時点」列を削除
df_drop = df.drop( columns=['時間軸コード', '時点'] )
# もしくはdf_drop = df.drop(['時間軸コード', '時点'], axis=1)

# 「男」、「女」列だけを取り出す
df_select = df[['男','女']]
# もしくはdf_select = df.loc[:, ['男','女']]

出力結果

  • 元データ
  • 列を削除したデータ
  • 列を選択したデータ

少し解説

drop関数

列の削除は、一般的にはdf.drop(['時間軸コード', '時点'], axis=1)を使います。

こちらの良いところは、axis=0(もしくはオプションなし)にすると列の削除もできるところです。

ただし、私の場合列って0だっけ?1だっけ?といつも悩むので、column=を使う方が便利だと思っています。

loc関数

こちらも今回コメントアウトしていますが、loc関数を使うといろいろと応用ができます。

loc[(取りたい行), (取りたい列)]という構文になります。

今回行はすべて取るため、:としていますが、例えば以下のようなことが簡単にできます。

  • 50行まで取る→ df.loc[:50, ['男','女']]
  • 40~60行を取る → df.loc[40:60, ['男','女']]
  • 70行以降を取る → df.loc[70:, ['男','女']]

astypeで数値型を文字列型に変換

前回紹介したstr関数(contains startswith endwith matchなど)は、文字列型にしか使えません。

Pandasでread_excelread_csvなどをすると自動的に型を割り当ててくれるので、便利ではあるのですが数値型にも上記の関数を使い時もあります。

その方法をお伝えします。

コード紹介

# インポート
import pandas as pd

# 列の最大表示数を7に設定
pd.set_option('display.max_columns', 7)
# 列の最大表示数を5に設定
pd.set_option('display.max_rows', 5)

# ファイルの取り込み
df = pd.read_excel("05k2-3.xlsx", skiprows=3, skipfooter=3)

print('【すべてのデータを表示】')
print(df)

df_contain = df[df['男'].astype(str).str.startswith('22')]
print('\n\n【男が「22」から始まるものを表示】')
print(df_contain)

出力結果

少し解説

df['男'] で列名「男」の中身を取り出します。

そのあとに.astype(str)を入れることで、文字列型に変換します。 よく使うものは以下です。

  • str: 文字列
  • int: 整数(int32で扱う)
  • float: 浮動小数点(float64で扱う)

その後にstr関数を使い、文字列のフィルタをかけています。 (この場合だと22から始まるもの)

ちなみにprintに書いている\nは改行の意味です。

Pandasでフィルタ操作(条件によるデータの絞り込み)

Excelでいうフィルタ機能をPythonで実現していきます。 データ操作は、いつも通りPandasで行います。

コード紹介

# インポート
import pandas as pd

# 列の最大表示数を7に設定
pd.set_option('display.max_columns', 7)
# 列の最大表示数を5に設定
pd.set_option('display.max_rows', 5)

# ファイルの取り込み
df = pd.read_excel("05k2-3.xlsx", skiprows=3, skipfooter=3)

print('すべてのデータを表示')
print(df)

df_equal = df[df['人口区分'] == '総人口']
print('人口区分が「総人口」のものを表示')
print(df_equal)

df_contain = df[df['人口区分'].str.contains('日本')]
print('人口区分に「日本」が含まれるものを表示')
print(df_contain)

df_range = df[(df['男女計'] >= 20) & (df['男女計'] < 40)]
print('男女計が20以上40未満のものを表示')
print(df_range)

出力結果

少し解説

文字列の条件

str関数の中にいくつか文字の条件を入れることができます。

  • contains 特定の文字列が含まれる(SQLでいうlikeですね)
  • startswith 特定の文字から始まる
  • endwith 特定の文字で終わる
  • match 特定の正規表現に一致するもの

条件の追加

今回は&をつけてAND条件をコードで紹介しました。

OR条件は|になります。

注意点として、 必ず1つの条件文を()で囲みましょう

set_optionでPandasデータの出力結果を省略させない

Pandasはデータ成型に非常に便利ですが、データを表示する時に良きに計らい勝手に省略してくれます。

ざっくり見るのにはよいのですが、やはりExcelのようにデータを全部見たいときありますよね。

困りごと

このような形で、11列目~20列目、5行目~93行目が省略されてしまいます。

解決策(コード紹介)

# インポート
import pandas as pd

# 列の最大表示数を100に設定
pd.set_option('display.max_columns', 100)
# 列の最大表示数を100に設定
pd.set_option('display.max_rows', 100)

# ファイルの取り込み
df = pd.read_excel("sample_data.xlsx")

# 結果の表示
df

出力結果

すべて表示してくれました。

少し解説

set_optionを使うとPandasの設定を変えることができます。 python reset_option('all')とすると、設定値をすべてリセットできます。