Подтвердить что ты не робот

Удалите нечисловые строки в одном столбце с помощью pandas

Существует так называемый dataframe, и у него есть один нечистый столбец "id", который он представляет собой числовой столбец

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

Есть ли сжатый способ удалить строки, потому что tt и de не являются числовыми значениями

tt,D
de,G

чтобы сделать dataframe чистым?

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

Ответ 1

Вы можете использовать стандартный метод строк 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

Edit. Добавить время

Хотя в случае с pd.to_numeric не используется метод apply, он почти в два раза медленнее, чем при применении np.isnumeric для столбцов str. Также я добавляю опцию с использованием панд 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)

Ответ 2

Используя pd.to_numeric

In [1079]: df[pd.to_numeric(df['id'], errors='coerce').notnull()]
Out[1079]:
  id  name
0  1     A
1  2     B
2  3     C
4  4     E
5  5     F

Ответ 3

Учитывая, что df является вашим фреймворком данных,

import numpy as np
df[df['id'].apply(lambda x: isinstance(x, (int, np.int64)))]

Что это значит - передать каждое значение в столбце id функции isinstance и проверяет, есть ли это int. Затем он возвращает логический массив и, наконец, возвращает только строки, где есть True.

Если вам также необходимо учитывать значения float, другой вариант:

import numpy as np
df[df['id'].apply(lambda x: type(x) in [int, np.int64, float, np.float64])]

Обратите внимание, что в любом случае нет места, поэтому вам нужно переназначить его на исходный df или создать новый:

df = df[df['id'].apply(lambda x: type(x) in [int, np.int64, float, np.float64])]
# or
new_df = df[df['id'].apply(lambda x: type(x) in [int, np.int64, float, np.float64])]

Ответ 4

x.isnumeric() не проверяет возврат True, когда x имеет тип float.

Один из способов отфильтровать значения, которые можно преобразовать в float:

df[df['id'].apply(lambda x: is_float(x))]

def is_float(x):
    try:
        float(x)
    except ValueError:
        return False
    return True