LoginSignup
8
10

More than 3 years have passed since last update.

(Python)Excelファイルを読み込んで指定データのみを絞り込む方法

Last updated at Posted at 2019-09-02

Excelファイル内の指定社員コードのデータを検索して確認したい。

Excelファイル内の指定社員コードのデータをpythonで読み込んで、検索したいと思います。

sample.xlsx
excelDemo_2_1.png

0. pandas のインストール

今回は pandas を使用します。(pandas の依存ライブラリは下記の通りです。)

openpyxl==2.6.3
pandas==0.25.1
xlrd==1.2.0

下記のコマンドでインストールします。

pip install pandas openpyxl xlrd

1.ExcelFileの読み込み(pandas.read_excel または pandas.ExcelFile の parse メソッド)

Excelファイルの読み込み処理には pandas.read_excel または、pandas.ExcelFile インスタンスの parse メソッドを使用して、pandas.DataFrame に変換します。 (今回は pandas.ExcelFile インスタンスの parse メソッドを使用しています。)

readExcelModule.py
from pandas import DataFrame, Series, ExcelFile
import os

def isExcelFilePath(filepath:str)->bool:
    return (filepath.endswith('.xlsx')  
            or filepath.endswith('.xls'))

def getExcelFile(filepath:str)->ExcelFile:
    if (not os.path.exists(filepath)
        or (not isExcelFilePath(filepath))):
        return None
    return ExcelFile(filepath)

def getDataFromExcelFile(excelFile:ExcelFile)->DataFrame:
    return excelFile.parse(
        index_col=None
    )

dataFrame = getDataFromExcelFile(
    getExcelFile('./sample.xlsx')
)
print (dataFrame)

このときindex_col=None を指定しないと、一列目がindex として扱われてしまうので、index_col=None を指定するようにします。

出力結果.txt
  社員コード   社員名    社員名かな 性別       生年月日
0  A000  田中太郎   たなかたろう  男 1980-01-01
1  C123  多田久信  おおたひさのぶ  男 1980-01-01
2  C012  安村花子  やすむらはなこ  女 1980-01-01

2. dataFrame のアクセサ[]に検索条件の絞り込み処理を渡す

readExcelModule.py
searchedDataRow = dataFrame[dataFrame['社員コード'] == 'A000']

dataFrame[dataFrame[検索対象列] == 検索条件の値]と書くことで、DataFrame内の絞り込みができ社員コードが「A000」の社員データを取得できます。

出力結果.txt
  社員コード   社員名   社員名かな 性別       生年月日
0  A000  田中太郎  たなかたろう  男 1980-01-01

(補足)「dataFrame[検索対象列] == 検索条件の値」は何を返すのか?

dataFrameのアクセサに渡した「dataFrame[検索対象列] == 検索条件の値」という記述は、DataFrameの各行が検索条件にマッチするかのbool値リストを返すようです。

readExcelModule.py
print (dataFrame['社員コード'] == 'A000')
出力結果.txt
0     True
1    False
2    False
Name: 社員コード, dtype: bool

よって、全行の検索条件にマッチしたものだけがTrueとして渡されるため、結果として検索結果が取得できるようでした。

なので下記のような比較演算子を使用した検索も可能なようです。

readExcelModule.py
# dataFrameの「固定支給額」が 380000 超のデータを検索する
searchedDataRow = dataFrame[dataFrame['固定支給額'] > 380000]

(補足2)Header行なしの データのみを読み込みたい場合

Header行を読み込みデータに含めたくない場合、ExcelFile の parse(または pandas.read_excel)で下記の設定をします。

  • skiprows を設定する
  • header=None を設定する

これで、1行目をスキップして、header をただの連番として読み込めました。

readExcelModule.py
def getDataFromExcelFile(excelFile:ExcelFile)->DataFrame:
    return excelFile.parse(
        index_col=None,
        skiprows=1,
        header=None
    )

出力結果.txt
      0     1        2  3          4
0  A000  田中太郎   たなかたろう  男 1980-01-01
1  C123  多田久信  おおたひさのぶ  男 1980-01-01
2  C012  安村花子  やすむらはなこ  女 1980-01-01

まとめ

  • Excel を pandas.DataFrameとして読み込む。
  • DataFrameの絞り込みを行うときは、DataFrame自体の絞り込み結果のbool値のリストを渡す。
  • header=None と skiprows を設定するとヘッダの読み込みを制御できる。

以上を行うことで PythonでExcelファイルを読み込んで指定したデータを確認できました。

20210201 追記 絞り込みの処理で「FutureWarning: elementwise comparison failed; returning scalar instead, but in the future will perform elementwise comparison res_values = method(rvalues) 」と表示される場合

エラーメッセージを確認したところバージョンアップでpythonとpandasの挙動が、自分が記事を書いたときから変わったところがあるようです。

以下のバージョンで再検証しました。

py --version
Python 3.7.9
et-xmlfile-1.0.1 
jdcal-1.4.1 
numpy-1.20.0 
openpyxl-3.0.6 
pandas-1.2.1 
python-dateutil-2.8.1 
pytz-2021.1 
six-1.15.0 
xlrd-2.0.1

再検証したところ、dataFrameに対する比較演算処理(dataFrame['商品番号'] == 1))が以前はboolのSeries値が返っていましたが、ただのbool値を返すように変わったようです。
https://stackoverflow.com/questions/40659212/futurewarning-elementwise-comparison-failed-returning-scalar-but-in-the-futur

以下のコードで動きました。

dataFrame = getDataFromExcelFile(
    getExcelFile('./商品リスト.xlsx')
)
print (dataFrame)
searchedDataRow = dataFrame[dataFrame['商品番号'].isin([1])]
print (searchedDataRow)
 py .\demo.py
   商品番号 商品名   価格
0     1   a  100
1     2   b  200
2     3   c  300
3     4   d  400
   商品番号 商品名   価格
0     1   a  100

(教えて頂きありがとうございました。
記事も更新しました。)

以上です。

8
10
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
10