【python】複雑な条件下でのデータ抽出(str.contains/str.lenを列に適用するなど)

複雑な条件下でのデータ抽出 Python

前提

  • 環境:Google Colaboratory
    使用したコードはを参照
  • OS:Mac
  • dfという変数にデータを代入(以下ソースコード)※pandasとnumpyのimport
import numpy as np
import pandas as pd
df = pd.read_excel("sampleデータベース2.xlsx")

使用データ:アンケートデータ(数値だけでなく文字もあり)
詳細:データサイズ:1000 ✖︎ 137
※以下、上から5行4列を表示(カラム名が長いものが多いので全ては表示不可)

※データを手元に置きたい場合は以下からダウンロードをお願いします
https://docs.google.com/spreadsheets/d/1PUf72NH4cY9vuYe96A8IkOKl5-1q6zyp/edit?usp=sharing&ouid=111634202063271684226&rtpof=true&sd=true

列名(カラム名)に特定の文字が入った”列”の抽出

列名(カラム名)に”満足”という言葉が入った列を抽出

以下赤枠部分が欲しい。(分かりやすいように”満足”という言葉を赤く塗ってます

★以下コードで解決(以下で抽出が出来るので、変数なりに入れてください。以降同じく)

df.loc[:, df.columns.str.contains("満足")]

※str.containsを列名に適用している(Q. とか、特定の名称が入った列だけを抽出とかにも使える)

列名(カラム名)に”満足”という言葉が入った列と”サービス”という言葉が入った列を抽出

以下赤枠部分が欲しい。(分かりやすいように”満足”という言葉と”サービス”という言葉を赤く塗ってます

★以下コードで解決

df.loc[:, df.columns.str.contains("満足|サービス")]

※”|”を使用することで「いずれかの文字を含む」ものに拡張

列名(カラム名)に”満足”という言葉が入っていない列を抽出

以下赤枠部分が欲しい。

★以下コードで解決

df.loc[:, ~df.columns.str.contains("満足")]

※分かりづらいが、df.columnsの前に “~” を前に付けているだけ。もちろん同じ方法で、列名(カラム名)に”満足”という言葉と”サービス”という言葉が入っていない“列”の抽出も可能(以下コード)

df.loc[:, ~df.columns.str.contains("満足|サービス")]

列名(カラム名)の文字数が○文字以上の”列”の抽出

列名(カラム名)の文字数が9文字以上の列の抽出

以下赤枠部分がほしい。(緑枠部分に着眼)

★以下コードで解決

df[df.columns[df.columns.str.len() >= 9]]

※columnsの名前の文字数の長さ(len)が9以上の列の抽出

列名(カラム名)の文字数が9文字以上14文字以下の列の抽出

※あまり使わないと思うので以下にコードを貼り付けるだけとする

df[df.columns[(df.columns.str.len() >= 9) & (df.columns.str.len() <= 14)]]

列名(カラム名)の文字数が10文字ぴったりの列の抽出

※これも滅多に使わないと思うので以下にコードを貼り付けるだけとする

df[df.columns[(df.columns.str.len() == 10)]]

データ(セル)の中に特定の数字が入っている”列”の抽出

※いわゆるアンケートデータで、10点評価のものだけ抽出したいが、1つ1つの項目名に”(1-10点評価)”とか”(1-5点評価”)とかが入っていない場合。(入っていれば本記事1つ目の「特定の文字が入った列の抽出」で抽出できるが…)

データ(セル)の中に10の数字が入っている列の抽出

以下緑枠の中に10の数値が入っているかを見て、入っている列(赤枠)を抽出する。

★以下コードで解決

df[df.columns[np.any(df.values == 10, axis=0)]]

※valuesに10の数値が入っているcolumnsの指定
※注意:idなどの連番が入っている列も一緒に抽出されてしまうので、そのような部類のものは別途削除が必要

データ(セル)の中に6以上10以下の数字が入っている列の抽出

アンケートデータの1-10点で、基本的には10点のデータが入っているとは思うが、万が一10点が無かった場合の対処法。

※注意:”==” 以外の比較演算子、”>=” や “<=” などを使う場合は、文字列が入っていないデータを対象に上記操作を行う必要がある(TypeError: ‘>=’ not supported between instances of ‘str’ and ‘int’ が出るので)
以下コード↓

df2 = df.apply(lambda s:pd.to_numeric(s, errors='coerce')).dropna(axis=1, how="all")
df2[df2.columns[np.any((df2.values >= 6) & (df2.values <= 10), axis=0)]]

1行目:データ(セル)の中に文字列が入っている”列”だけを削除している(以下詳細)
df.apply(lambda s:pd.to_numeric(s, errors=’coerce’)) は、pd.to_numeric という、数値型に変換できる値は数値型に変換、数値型に変換できない文字列はNaNで埋めてくれるメソッドをデータ全てに使用している(イメージは以下)

その後、全てにNaNが入っている列を削除する .dropna(axis=1, how=”all”) を適用。
上記操作を行ったデータの中に6以上10以下の数字が入っている列の抽出を行い、終了。
※idなどの連番が入っている列に注意(一緒に抽出されてしまうので)
※今回はデータ(セル)の中に文字列が入っている”列”だけを削除しているということで、言い換えればデータ(セル)の中に文字列が入っていない”列”だけを抽出しているともいえる

タイトルとURLをコピーしました