

エクセルの特定のカラム「`column`」のデータを数字か数字以外なのかをチェックしたいと考えています。行った内容として、`isdigit`を使ってチェックしようとしてのですが、以下だと`df`が文字列と判断されません。`pandas`で読み込んだExcelデータを格納した変数`df`を文字列として判断するにはどのようにすればよろしいでしょうか。  
条件としまして、一個一個データを取りだして、数字なのかを確認したく、まとめて一括での確認ではないほうが良いです。  
エクセルファイルを読み込むために`pandas`を利用しているのは特に意味はありません。  
他に良い方法があればご教授いただければ幸いです。

[code]

    import pandas as pd
    df=pd.read_excel("test.xlsx",sheet_name="sheet1")
    for df_ch in df["column"]：
       if df_ch.isdigit():
            print("数字")
    　 else:
            print("数字以外")
    
[/code]

エクセルデータ

[![画像の説明をここに入力](https://i.stack.imgur.com/7UwqU.png)](https://i.stack.imgur.com/7UwqU.png)

[code]

    import pandas as pd
    df=pd.read_excel("test.xlsx",sheet_name="sheet1",header=None,names=['column'],dtype=str)
    for df_ch in df['column']:
       if df_ch.isdigit():
          print("数字")
       else:
          print("数字以外")
    
[/code]

上記で試してみましたが、以下のようなエラーが発生してしまいます。  
何処が原因なのでしょうか。

[code]

      if df_ch.isdigit():
    AttributeError: 'float' object has no attribute 'isdigit'
    
[/code]


CC BY-SA 4.0
2022-09-01T02:45:59.743
90862
2023-11-12T02:04:20.513
2022-09-01T06:18:38.517
3060
54115
question
python pandas excel
エクセルのデータを数字か数字以外かでチェックしたい


もしも指定のカラムが数値項目だと認識されているなら `isdigit()` はこのような感じのエラーがでるはず => `AttributeError:
'int' object has no attribute 'isdigit'`

※ そのようなエラーが発生しているならば質問に明記しておいたほうがよいでしょう

このようなデータを文字列として扱うには `.astype(str)` 利用するとよいかも

[code]

    >>> import pandas as pd
    >>> df = pd.DataFrame({'A':[100,200],'B':[110,120],'C':[210,300]})
    >>> df
         A    B    C
    0  100  110  210
    1  200  120  300
    >>> df.dtypes
    A    int64
    B    int64
    C    int64
    dtype: object
    >>> df['C'].astype(str)
    0    210
    1    300
    Name: C, dtype: object
    >>> [v.isdigit() for v in df['C'].astype(str)]
    [True, True]
    
[/code]


CC BY-SA 4.0
2022-09-01T05:32:34.570
90866
2022-09-01T05:32:34.570
43025
90862
answer


色々と微調整というか、こんな事前準備や処理が必要になります。

  * 列名の`column`を定義している所がありません。以下のいずれかの対処が必要になります。

    * 提示されたExcel画像は1行目からデータ(`0001`)が入っていますが、ここに列名用の行を挿入し、列名`column`をいれておく
    * Excelの内容を変更しないのなら、[read_excel()](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_excel.html)の時にパラメータとして`header=None`と`name=`に列名リスト(画像の場合1列だけなので`['column']`)を指定しておく
    * 列名は指定しなくても`0`から始まる連番のインデックス(Excel列の`A,B,C`が`0,1,2`に相当)が割り振られているので、それを利用する。パラメータに`header=None`は指定しておく。
  * デフォルトでは数値に変換できるデータは極力数値(intやfloat)に変換してDataFrameに格納されます。以下のいずれかの対処が考えられます。

    * read_excel()時に全てを文字列として扱うようにパラメータに`dtype=str`を指定する。
    * `for`ループのイテレータを指定する時にデータフレームの列そのまま(`df['column']`)ではなく、文字列に変換したシリーズ(`pd.Series(df['column'],dtype='string')`)として作成する。

例えばこんな処理のいずれかになるでしょう。  
いったん全部のデータを文字列として読み込む：

[code]

    import pandas as pd
    df=pd.read_excel("test.xlsx",sheet_name="sheet1",header=None,names=['column'],dtype=str)
    for df_ch in df['column']:
       if df_ch.isdigit():
          print("数字")
       else:
          print("数字以外")
    
[/code]

チェックする時にその列だけ文字列に変換する：

[code]

    import pandas as pd
    df=pd.read_excel("test.xlsx",sheet_name="sheet1",header=None,names=['column'])
    for df_ch in pd.Series(df['column'],dtype='string'):
       if df_ch.isdigit():
          print("数字")
       else:
          print("数字以外")
    
[/code]

* * *

**追記**

私の1つ目の回答を試してみてエラーとなったのは、空欄が何処かに存在したためでしょう。  
こんな記事を参考に、read_excel()のパラメータに`keep_default_na=False`を追加するか、読み取って出来たdfを`df=df.fillna('')`で処理すれば良いでしょう。  
[Python Pandas read_excel dtype str replace nan by blank ('') when reading or
when writing via to_csv](https://stackoverflow.com/q/45148292/9014308)  
[pandas.read_excel](https://pandas.pydata.org/pandas-
docs/stable/reference/api/pandas.read_excel.html)  
[pandas.DataFrame.fillna](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.fillna.html)

一応パラメータに`keep_default_na=False`を追加する方が推奨ですね。  
`df=df.fillna('')`の処理だと、その前に`read_excel()`の読み込みで`NaN`ではなく浮動小数点数と見做せるデータが1つでもあった時にその列全体が浮動小数点数として扱われてしまうので。


CC BY-SA 4.0
2022-09-01T05:34:53.487
90867
2022-09-01T07:34:49.890
2022-09-01T07:34:49.890
26370
26370
90862
answer


`pandas`を使う必要がなければ、`openpyxl`でExcelを読み込んでセルの型を取得する方法があります。

下記はセルの[`data_type`](https://openpyxl.readthedocs.io/en/2.5.14/api/openpyxl.cell.cell.html)プロパティでセルの型を取得するサンプルコードです。(要`pip
install openpyxl`)

**サンプルコード**

[code]

    from openpyxl import load_workbook
    wb = load_workbook("test.xlsx")
    ws = wb["Sheet1"]
    column = ws["A"]
    for row in range(1, len(column)):
        cell = column[row]
        ts = "数字" if cell.data_type == "n" else "数字以外" 
        print(f"{cell.value} は {ts}です")
    
[/code]


CC BY-SA 4.0
2022-09-01T06:06:10.920
90868
2022-09-01T06:06:10.920
9820
90862
answer

[code]

    import pandas as pd
    import numpy as np
    
    df=pd.read_excel("test.xlsx",sheet_name="sheet1",header=None,names=['column'],dtype=str)
    
    print(np.where(df['column'].str.isdigit(), '数字', '数字以外'))
    
    #
    ['数字' '数字' '数字' '数字' '数字' '数字' '数字' '数字' '数字' '数字' '数字' '数字' '数字' '数字'
     '数字' '数字' '数字' '数字']
    
[/code]


CC BY-SA 4.0
2022-09-01T06:08:16.277
90869
2022-09-01T06:08:16.277
47127
90862
answer


「数字」として判定する条件があいまいであるため、整数値かどうかの判定としました。  
また、'0003などの入力値は文字列として判断したいのか、数値として判断したいのかわからないため、今回は数値として判断しました。

## test.xlsx

[code]

    ['Sheet1'の'A'列に以下のデータを入力]
    1
    '0002.2
    '0003
    'a'
    '0004
    '0005
    
    
[/code]

## ソースコード

[code]

    import pandas as pd
    import pathlib
    
    file_path = pathlib.Path(__file__).parent / 'test.xlsx'
    
    df = pd.read_excel(file_path, sheet_name=0, header=None)
    for d in df[0]:
        isDigit = False
        if isinstance(d, str):
            if d.isdigit():
                isDigit = True
        elif isinstance(d, int):
            isDigit = True
    
        if isDigit:
            print(repr(d), '整数値です。')
        else:
            print(repr(d), '整数値以外です。')
    
    
[/code]

## 出力結果

[code]

    1 整数値です。
    '0002.2' 整数値以外です。
    '0003' 整数値です。
    'a' 整数値以外です。
    '0005' 整数値です。
    
[/code]


CC BY-SA 4.0
2022-09-01T06:16:33.337
90870
2022-09-01T06:16:33.337
32891
90862
answer