Python
 Computer >> コンピューター >  >> プログラミング >> Python

PandasのSeriesから完全平方数を抽出・フィルタリングするPythonプログラム

データ分析では、数値の系列(Series)の中から特定の条件を満たす要素だけを取り出したい場面がよくあります。本記事では、PandasのSeriesから完全平方数(4、9、16、25のように、ある整数の2乗で表せる数)だけをフィルタリングする方法を、複数のアプローチでわかりやすく解説します。

入力例と出力例

次のようなSeriesを想定します。

0    14
1    16
2    30
3    49
4    80
dtype: int64

この中から完全平方数である要素だけを抽出すると、結果は次のようになります。

1    16
3    49
dtype: int64

解法1:filter()とlambda式を使う方法

最もシンプルなのが、組み込み関数 filter() とlambda式を組み合わせる方法です。手順は以下の通りです。

  • PandasでSeriesを定義します。

  • lambda式の中で「値の平方根を四捨五入して2乗した結果が、元の値と一致するかどうか」を判定します。

  • isin() 関数を使って、元のSeriesから該当する要素だけを抽出します。

サンプルコード

import pandas as pd
import math as m

l = [14, 16, 30, 49, 80]
data = pd.Series(l)
print("元のSeries:")
print(data)

# filter()とlambda式で完全平方数のみを抽出
result = pd.Series(filter(lambda x: x == int(m.sqrt(x) + 0.5) ** 2, l))
print("Series内の完全平方数:")
print(data[data.isin(result)])

実行結果

元のSeries:
0    14
1    16
2    30
3    49
4    80
dtype: int64
Series内の完全平方数:
1    16
3    49
dtype: int64

ポイントは int(m.sqrt(x) + 0.5) の部分です。m.sqrt() による平方根計算には浮動小数点誤差が伴うため、単純に切り捨てると誤判定が発生する恐れがあります。+0.5 を加算して四捨五入することで、正確な判定を実現しています。

解法2:forループとisin()を使う方法

処理の流れをより明示的に記述したい場合は、forループで各要素を順番にチェックする方法も有効です。初心者にもロジックが理解しやすいのが特徴です。

サンプルコード

import pandas as pd
import math as m

l = [14, 16, 30, 49, 80]
data = pd.Series(l)
print("元のSeries:")
print(data)

lis = []
for i in range(len(data)):
    if data[i] == int(m.sqrt(data[i]) + 0.5) ** 2:
        lis.append(data[i])

print("Series内の完全平方数:")
print(data[data.isin(lis)])

実行結果

元のSeries:
0    14
1    16
2    30
3    49
4    80
dtype: int64
Series内の完全平方数:
1    16
3    49
dtype: int64

解法3:math.isqrt()を使う方法(推奨)

Python 3.8以降では、整数の平方根を誤差なく計算できる math.isqrt() 関数が利用できます。浮動小数点演算を一切経由しないため、非常に大きな数値でも確実に判定できるのが最大の利点です。また、Seriesの apply() メソッドと組み合わせれば、コードを簡潔に書けます。

サンプルコード

import pandas as pd
import math

data = pd.Series([14, 16, 30, 49, 80])
result = data[data.apply(lambda x: math.isqrt(x) ** 2 == x)]
print("元のSeries:")
print(data)
print("Series内の完全平方数:")
print(result)

実行結果

元のSeries:
0    14
1    16
2    30
3    49
4    80
dtype: int64
Series内の完全平方数:
1    16
3    49
dtype: int64

まとめ

方法特徴
filter() + lambdaリストに対して手軽に使える定番の手法
forループ + isin()処理の流れが明快で、学習用にわかりやすい
math.isqrt()誤差ゼロで高速。Python 3.8以降なら第一候補

小規模なデータであればどの方法でも問題ありませんが、数値が大きくなる可能性がある場合は、浮動小数点誤差の影響を受けない math.isqrt() を使う方法が最も安全です。用途や環境に応じて、適切な手法を選択してください。

  1. Pythonで指定した数値がフィボナッチ数かどうかを判定する方法

    フィボナッチ数とは ある数値 n が与えられたとき、その数がフィボナッチ数列に含まれているかどうかを判定します。フィボナッチ数列は、f(0) = 0、f(1) = 1 を初期値とし、i ≥ 2 の各項について f(i) = f(i-1) + f(i-2) という漸化式で定義される数列です。 具体的には、数列は 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ... のように続きます。たとえば入力が n = 13 の場合、13 はフィボナッチ数列に含まれるため、出力は True になります。 解法のアプローチ:黄金比を利用した判定 この問題は、黄金比(φ ≈ 1.618...

  2. Pythonで指定されたインデックスに基づいて文字列をシャッフルする方法

    文字列 s とインデックスのリスト ind が与えられ、両者は同じ長さであるとします。文字列 s は、位置 i にある文字が最終的な文字列内の ind[i] の位置へ移動するようにシャッフルされます。このとき、シャッフル後の最終的な文字列を求める必要があります。例えば、入力が s = ktoalak、ind = [0,5,1,6,2,4,3] の場合、出力は kolkata となります。解決手順この問題を解くには、以下の手順に従います。fin_str を s と同じサイズのリストとして作成し、0で初期化するs 内の各インデックス i と各文字 v に対して、次の操作を行うfin_str[ind