質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

Q&A

解決済

2回答

3778閲覧

【pandas】列に浮動小数点を含むDataFrame同士の比較方法

kara1

総合スコア11

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

0グッド

0クリップ

投稿2021/07/29 14:27

編集2021/07/30 14:09

pandasのDataFrameを戻り値とする関数をテストする中で、
期待値として用意したDataFrameと、出力値のDataFrameの比較結果が一致しません。

期待値と出力値をそれぞれコンソールに出力してみましたが、
見た目上は同じ値となっています。

ただ、テスト対象の関数にて、浮動小数点の乗算を行っており、
この箇所が原因となり、期待値と出力値が一致しないのではないかと考えています。

もしかすると、pytestの書き方にも原因があるかもしれませんが、
浮動小数点を含むDataFrame同士の比較をどのように書けばよいでしょうか?


  • テスト対象の関数(model.py)
import pandas as pd def calc_square(df) -> pd.DataFrame: df_result: pd.DataFrame = df.copy() df_square: pd.DataFrame = df['height'] ** 2 df_result.insert(2, 'height^2', df_square) return df_result
  • テストケース(test_model.py)
import pandas as pd import model def test_01(): # 入力値 dict_input = {'name': ['userA'], 'height': [1.11]} df_input: pd.DataFrame = pd.DataFrame(data = dict_input) # 期待値 dict_expected = {'name': ['userA'], 'height': [1.11], 'height^2': [1.2321]} df_expected: pd.DataFrame = pd.DataFrame(data = dict_expected) # 出力値 df_output: pd.DataFrame = model.calc_square(df_input) # 比較 assert df_expected.equals(df_output)
  • テスト実行結果(一部抜粋)
E assert False E + where False = <bound method NDFrame.equals of name height height^2\n0 userA 1.11 1.2321>( name height height^2\n0 userA 1.11 1.2321) E + where <bound method NDFrame.equals of name height height^2\n0 userA 1.11 1.2321> = name height height^2\n0 userA 1.11 1.2321.equals tests\src\test_model.py:41: AssertionError =============================================== short test summary info =============================================== FAILED tests/src/test_model.py::test_01 - assert False ============================================= 1 failed in 2.50s =============================================

■追記

DataFrame同士で比較するために、比較関数を作成する必要があるとのことで、
当初の質問のような、DataFrame同士の比較という形ではなく、
DataFrameの列単位での比較という形でテストを実装しました。

  • テストケース(test_model.py)
import pandas as pd import model def test_01(): # 入力値 dict_input = {'name': ['userA'], 'height': [1.11]} df_input: pd.DataFrame = pd.DataFrame(data = dict_input) # 期待値 dict_expected = {'name': ['userA'], 'height': [1.11], 'height^2': [1.2321]} df_expected: pd.DataFrame = pd.DataFrame(data = dict_expected) # 出力値 df_output: pd.DataFrame = model.calc_square(df_input) # 比較 assert df_expected.equals(df_output.round(4) # round()にて小数点以下4桁で丸め

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

浮動小数の配列同士を比較する場合はnp.allclose()を用います。
numpy.allclose — NumPy Manual

python

1df1 = pd.DataFrame([[1.11 ** 2]]) 2df2 = pd.DataFrame([[1.2321]]) 3 4all(df1 == df2) # -> False 5df1.equals(df2) # -> False 6np.allclose(df1, df2) # -> True

投稿2021/07/30 06:33

kirara0048

総合スコア1399

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kara1

2021/07/30 14:10

ご回答ありがとうございます。 NumPyを使用することで、浮動小数同士の比較が可能なのですね。 NumPyを使った例も試してみます。 ありがとうございました。
guest

0

ベストアンサー

原因は浮動小数点数として異なるからです。
以下のように表示桁数を変更して見ればわかります。

python

1>>> df1 = pd.DataFrame([[1.11 ** 2]]) 2>>> df2 = pd.DataFrame([[1.2321]]) 3>>> 4>>> with pd.option_context('display.precision', 16): 5... print('df1 :') 6... print(df1) 7... print('df2 :') 8... print(df2) 9... 10df1 : 11 0 120 1.2321000000000002 13df2 : 14 0 150 1.2321 16>>> with pd.option_context('display.precision', 4): 17... print('df1 :') 18... print(df1) 19... print('df2 :') 20... print(df2) 21... 22df1 : 23 0 240 1.2321 25df2 : 26 0 270 1.2321

解決するには、対象が浮動小数点数を何らかの形で含む場合には誤差が指定した範囲にあるかどうかを調べるような比較関数を自分で作成するしかありません。
汎用的に使えるものを作るとなると、一ヶ月で作るのは難しいように思います。
本当に汎用的なものを作るのは無理です。
テストに必要な機能に限定して、比較関数を作成するしかありません。

投稿2021/07/29 22:38

編集2021/07/29 22:45
ppaul

総合スコア24670

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kara1

2021/07/30 14:03 編集

ご回答ありがとうございます。 また、例を用いて内部で浮動小数点がどのように解釈されているかを提示いただき、ありがとうございます。 比較関数を自分で作成するしかない、という着地点が見えただけでも、 質問して良かったです。 今回は当初の質問の意図とは離れてしまいますが、 DataFrame同士の比較という形ではなく、 DataFrameの中の列単位での比較にてテストを実装しました。 根本的な解決...というわけではないですが、こちらのコードを追記して、 私の中では質問はクローズとさせていただきます。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問