1. ホーム
  2. python

pandasで1列の非数値の行を削除する

2023-12-12 04:46:04

質問

以下のようなデータフレームがあり、1つの不潔な列 'id' があります。

id, name
1,  A
2,  B
3,  C
tt, D
4,  E
5,  F
de, G

ttとdeは数値ではないので、行を削除する簡潔な方法はありますか?

tt,D
de,G

で、データフレームをきれいにする?

id, name
1,  A
2,  B
3,  C
4,  E
5,  F

どのように解決するのですか?

文字列の標準的なメソッドを使用することができます isnumeric の各値に適用し id カラムの各値に適用します。

import pandas as pd
from io import StringIO

data = """
id,name
1,A
2,B
3,C
tt,D
4,E
5,F
de,G
"""

df = pd.read_csv(StringIO(data))

In [55]: df
Out[55]: 
   id name
0   1    A
1   2    B
2   3    C
3  tt    D
4   4    E
5   5    F
6  de    G

In [56]: df[df.id.apply(lambda x: x.isnumeric())]
Out[56]: 
  id name
0  1    A
1  2    B
2  3    C
4  4    E
5  5    F

あるいは id をインデックスとして使いたい場合は、そうすることもできます。

In [61]: df[df.id.apply(lambda x: x.isnumeric())].set_index('id')
Out[61]: 
   name
id     
1     A
2     B
3     C
4     E
5     F

編集する タイミングを追加する

というケースもありますが pd.to_numeric が使われていない apply メソッドを適用した場合と比較して、約2倍遅くなります。 np.isnumeric を適用した場合 str カラムになります。また、pandasを使ったオプションも追加しています。 str.isnumeric を使う方が、より少ない入力で、かつ、より速く pd.to_numeric . しかし pd.to_numeric はより一般的なもので、(文字列だけでなく)あらゆるデータ型で動作します。

df_big = pd.concat([df]*10000)

In [3]: df_big = pd.concat([df]*10000)

In [4]: df_big.shape
Out[4]: (70000, 2)

In [5]: %timeit df_big[df_big.id.apply(lambda x: x.isnumeric())]
15.3 ms ± 2.02 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [6]: %timeit df_big[df_big.id.str.isnumeric()]
20.3 ms ± 171 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [7]: %timeit df_big[pd.to_numeric(df_big['id'], errors='coerce').notnull()]
29.9 ms ± 682 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)