как заменить недопустимый ввод типа данных на «None» в фрейме данных pandas

#python #python-3.x

#python #python-3.x

Вопрос:

Хотел бы заменить все недопустимые типы данных в столбцах «число» и «дата». Начальная таблица выглядит следующим образом:

 name    number      date
a       1.2         123.2
b       123.2       3/13/2019
c       2.3         3/14/2019
d       569         3/15/2019
e       abc         3/15/2019
f       30          abc 
g       39.8        -3
h       3/21/2019   3/19/2019
i       -395        3/20/2019
j       4           3/21/2019
 

после очистки таблица должна выглядеть следующим образом: все недопустимые введенные типы данных были заменены на none:

 name    number      date
a       1.2         
b       123.2       3/13/2019
c       2.3         3/14/2019
d       569         3/15/2019
e                   3/15/2019
f       30           
g       39.8        
h                   3/19/2019
i       -395        3/20/2019
j       4           3/21/2019
 

Я могу заменить только ввод строки на None, я не знаю, как заменить ввод числа на None в столбце «дата» и не знаю, как заменить ввод даты и времени на None в столбце «число». если в столбце datetime есть числовой ввод или ввод datetime в столбце number, мой код показывает ошибки:

объект ‘float’ не имеет атрибута ‘strftime’

Преобразование типа данных datetime2 в тип данных datetime привело к значению вне диапазона.

 df['date']=df['date'].apply(lambda x: None if str(type(x))=="<class 'str'>" else x)

df['date']=df['date'].apply(lambda x: x.strftime('%m/%d/%Y')if not pd.isnull(x) else '')

df['date'] = pd.to_datetime(df['date'], errors='coerce')

df['number'] = df['number'].apply(lambda x: None if str(type(x))=="<class 'str'>" else x)
 

Комментарии:

1. Какое сообщение об ошибке вы получаете?

2. объект ‘float’ не имеет атрибута ‘strftime’ Преобразование типа данных datetime2 в тип данных datetime привело к значению вне диапазона.

Ответ №1:

Мог бы быть лучший способ, но метод, который сразу пришел мне в голову, — использовать регулярное выражение. Вот решение.

 import numpy as np
import pandas as pd
import re

>>>df
name    number      date
a       1.2         123.2
b       123.2       3/13/2019
c       2.3         3/14/2019
d       569         3/15/2019
e       abc         3/15/2019
f       30          abc 
g       39.8        -3
h       3/21/2019   3/19/2019
i       -395        3/20/2019
j       4           3/21/2019


# Matches m/dd/yyyy
dt_pattern = r'[0-9]{1,2}/[0-9]{1,2}/[0-9]{4}'
dt = re.compile(dt_pattern)
# alphabet strings
wd_pattern = r'[a-zA-Z] '
wd = re.compile(wd_pattern)

df.loc[:,'date'] = [d if dt.match(str(d)) else np.nan for d in  df.loc[:, 'date']]
df.loc[:,'number'] = [d if not any([wd.match(str(d)), dt.match(str(d))]) else np.nan for d in  df.loc[:, 'number']]
df['date'] = pd.to_datetime(df['date'], errors='coerce')

>>>df
  name number       date
0    a    1.2        NaT
1    b  123.2 2019-03-13
2    c    2.3 2019-03-14
3    d    569 2019-03-15
4    e    NaN 2019-03-15
5    f     30        NaT
6    g   39.8        NaT
7    h    NaN 2019-03-19
8    i   -395 2019-03-20
9    j      4 2019-03-21
 

Комментарии:

1. привет, спасибо за вашу помощь, но я получаю другой результат, как показано на рисунке, не хватает ли какой-нибудь строки?

2. Можете ли вы кратко описать различия?

3. имя номер дата 0 a 1.2 NaT 1 b 123.2 NaT 2 c 2.3 NaT 3 d 569 NaT 4 e NaN NaT 5 f 30 NaT 6 g 39.8 NaT 7 h 2019-03-21 00:00:00 NaT 8 i -395 NaT 9 j 4 NaT

4. в number col удаляется только строковый ввод как NaN, остается ввод даты и времени. в столбце даты все было изменено на NaT

5. Да, похоже, что ваше форматирование даты отличается, и они не распознаются как объект datetime. Как это выглядит в вашем raw-файле?