Main_df :

    Name    Age   Id     DOB
0   Tom     20   A4565  22-07-1993
1   nick    21   G4562  11-09-1996
2   krish   AKL  F4561  15-03-1997
3   636A    18   L5624  06-07-1995
4   mak     20   K5465  03-09-1997
5   nits    55   56541  45aBc
6   444     66   NIT    09031992

column_info_df:

   Column_Name  Column_Type
0   Name         string
1   Age          integer
2   Id           string
3   DOB          Date

Как я могу найти значение ошибки типа данных из основного DF. Например, из информации о столбце df мы видим, что «Имя» является строковым столбцом, поэтому в основном столбце «df» столбец «Имя» должен содержать либо строку, либо буквенно-цифровой код, за исключением того, что это ошибка. Мне нужно найти эти значения ошибки типа данных в отдельном df.

Ошибка вывода df:

   Column_Name   Current_Value   Exp_Dtype   Index_No.
0  Name             444           string        6
1  Age              444           int           2
2  Name            56441          string        6
0  DOB             4aBc           Date          5
0  DOB             09031992       Date          6

Я попробовал это:

for i,r in column_info_df.iterrows():
    if r['Column_Type'] == 'string':
          main_df[r['Column_Name']].loc[main_df[r['Column_Name']].str.match(r'[^a-z|A-Z]+')]
    elif r['Column_Type'] == 'integer':
          main_df[r['Column_Name']].loc[main_df[r['Column_Name']].str.match(r'[^0-9]+')]
    elif r['Column_Type'] == 'Date':

Я застрял здесь, потому что это RE не ловит все ошибки. я не знаю, как идти дальше?

1
harry 17 Дек 2019 в 18:19

2 ответа

Лучший ответ

Вот один из способов использования {{X0} },

Примечание : , хотя это будет проверять на основе шаблона и возвращать несоответствующие значения. Однако обратите внимание, что это не может проверять допустимые типы, например, если в столбце даты есть запись, которая выглядит как дата, но является недопустимой датой, это не идентифицирует это:

d={"string":".str.contains(r'[a-z|A-Z]')","integer":".str.contains('^[0-9]*$')",
                                 "Date":".str.contains('\d\d-\d\d-\d\d\d\d')"}
m=df.eval([f"~{a}{b}" 
   for a,b in zip(column_info_df['Column_Name'],column_info_df['Column_Type'].map(d))]).T

final=(pd.DataFrame(np.where(m,df,np.nan),columns=df.columns)
              .reset_index().melt('index',var_name='Column_Name',
                            value_name='Current_Value').dropna())
final['Expected_dtype']=(final['Column_Name']
                         .map(column_info_df.set_index('Column_Name')['Column_Type']))
print(final)

< Сильный > Выход :

    index Column_Name Current_Value Expected_dtype
6       6        Name           444         string
9       2         Age           AKL        integer
19      5          Id         56541         string
26      5         DOB         45aBc           Date
27      6         DOB      09031992           Date

Я согласен, что могут быть лучшие regex шаблоны для этой работы, но идея должна быть такой же.

0
anky_91 18 Дек 2019 в 06:33

Если я понял, что вы сделали, вы создали отдельные фреймы данных, которые содержат информацию о вашем основном.

Вместо этого я предлагаю использовать встроенные методы, предлагаемые пандами, для работы с фреймами данных.

Например, если у вас есть фрейм данных main , то:

main.info()

Даст вам тип объекта для каждого столбца. Обратите внимание, что столбец может содержать только один тип, так как он является серией, которая сама является ndarray.

Таким образом, в вашем столбце name не может быть ничего, кроме строк, которые вы бы пропустили. Вместо этого вы можете иметь значения NaN . Вы можете проверить их с помощью

main.describe()

Я надеюсь, что это помогло :-)

0
Nicolas Dupuy 17 Дек 2019 в 16:11