Принудительно применять типы фреймов данных и разрешать NaN

#python-3.x #pandas #dataframe

#python-3.x #pandas #фрейм данных

Вопрос:

Мне нужно инициализировать пустой фрейм данных pandas с определенными типами данных для столбцов, а затем добавить к фрейму данных некоторые строки, которые могут содержать не все столбцы, но содержимое столбца должно быть тем, которое объявлено при создании фрейма данных. Есть ли способ сделать это?

 record_list = [
                   { 'lastname'    : 'Ford',
          'firstname'  : 'Ana',
          'agreed'     : 0
                   },
                   { 'lastname'    : 'Snow',
          'agreed'     : 'a'
                    }
                    ]
    df = pd.DataFrame({
    'lastname'    : np.array([], dtype=np.object),
        'firstname'   : np.array([], dtype=np.object),                       
            'agreed'      : np.array([], dtype=np.int64)
                    })

for record in record_list:
    df = df.append([record], ignore_index=True)
  

Вышеописанное должно завершиться неудачей, потому что ‘согласовано’ — это string, а не int, но если это было int, то NaN следует поместить во фрейм данных для второй записи, даже если тип str .
Я также пробовал столбцы и dtype отдельно, но не сработало. Пожалуйста, помогите!

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

1. Каков именно ваш рабочий процесс и какая обработка ошибок вам нужна? Насколько велики данные и как часто вы будете это запускать? Я не знаю способа заставить pandas применять типы данных. Можете ли вы запустить этот процесс ввода данных вне pandas? В SQL или с помощью инструмента ETL?

2. Также ознакомьтесь с: tdda.info /… который, однако, тестируется ex-post, а не во время добавления данных

Ответ №1:

Не совсем ясно, чего вы, наконец, хотите. Но я объясняю то, что я понял. Думайте о pandas как о традиционной базе данных. Вы не можете поместить str и int в один столбец. Но по умолчанию в pandas, если в столбце с типом данных int есть NaN , данные всегда будут отображаться как десятичные, например. 0.0 Лучше сначала очистить данные и вставить в новый список, а затем прочитать непосредственно в фрейм данных.

 new_data = []
for item in record_list:
    agrd = item.get("agreed", None)
    if isinstance(agrd, int):
        new_data.append(item)
    else:
        item["agreed"] = None
        new_data.append(item)

df = pd.DataFrame(new_data)
  

Результат:

    agreed firstname lastname
0     0.0       Ana     Ford
1     NaN       NaN     Snow
  

Поскольку существует NaN, pandas всегда будет показывать десятичную дробь вместо int. Таким образом, вы можете заменить NaN на df.<columnname>.fillna(value=-1) , а затем преобразовать столбец с помощью df["columnname"] = df.columnname.astype(int)

Ответ №2:

Вы можете использовать pd.to_numeric() приведенное ниже для проверки после загрузки данных и обрабатывать их по своему усмотрению:

 df=df.append(record_list)
df.agreed=np.where(pd.to_numeric(df.agreed,errors='coerce').isna(),np.nan,df.agreed)
print(df)

  lastname firstname agreed
0     Ford       Ana      0
1     Snow       NaN    NaN