Преобразование столбца Pandas, содержащего NaNs, в dtype ' int`
Я читаю данные из a .csv-файл для фрейма данных Pandas, как показано ниже. Для одной из колонок, а именно id
, Я хочу указать тип столбца как int
. Проблема в id
серия имеет отсутствующие / пустые значения.
когда я пытаюсь бросить id
столбец в целое число при чтении .csv, я получаю:
df= pd.read_csv("data.csv", dtype={'id': int})
error: Integer column has NA values
альтернативно, я попытался преобразовать тип столбца после чтения, как показано ниже, но на этот раз я получаю:
df= pd.read_csv("data.csv")
df[['id']] = df[['id']].astype(int)
error: Cannot convert NA to integer
как я могу решить это?
9 ответов
отсутствие NaN rep в целочисленных столбцах является панды "Гоча".
обычный обходной путь-просто использовать поплавки.
мой вариант использования-это munging data перед загрузкой в таблицу DB:
df[col] = df[col].fillna(-1)
df[col] = df[col].astype(int)
df[col] = df[col].astype(str)
df[col] = df[col].replace('-1', np.nan)
удалить NaNs, преобразовать в int, преобразовать в str, а затем повторно вставить NANs.
Это не красиво, но он получает работу!
если вы можете изменить сохраненные данные, используйте значение sentinel для missing id
. Общий вариант использования, выводимый именем столбца, является то, что id
является целым числом, строго больше нуля, вы можете использовать 0
как значение sentinel, так что вы можете написать
if row['id']:
regular_process(row)
else:
special_process(row)
Предположим ваш DateColumn отформатирован 3312018.0 должны быть преобразованы в 03/31/2018 как струна. И некоторые записи отсутствуют или 0.
df['DateColumn'] = df['DateColumn'].astype(int)
df['DateColumn'] = df['DateColumn'].astype(str)
df['DateColumn'] = df['DateColumn'].apply(lambda x: x.zfill(8))
df.loc[df['DateColumn'] == '00000000','DateColumn'] = '01011980'
df['DateColumn'] = pd.to_datetime(df['DateColumn'], format="%m%d%Y")
df['DateColumn'] = df['DateColumn'].apply(lambda x: x.strftime('%m/%d/%Y'))
я столкнулся с этой проблемой, работая с pyspark. Поскольку это интерфейс python для кода, запущенного на jvm, он требует безопасности типов, и использование float вместо int не является опцией. Я работал над проблемой, обернув панд pd.read_csv
в функции, которая будет заполнять пользовательские столбцы пользовательскими значениями заполнения перед приведением их к требуемому типу. Вот что я в итоге использовал:
def custom_read_csv(file_path, custom_dtype = None, fill_values = None, **kwargs):
if custom_dtype is None:
return pd.read_csv(file_path, **kwargs)
else:
assert 'dtype' not in kwargs.keys()
df = pd.read_csv(file_path, dtype = {}, **kwargs)
for col, typ in custom_dtype.items():
if fill_values is None or col not in fill_values.keys():
fill_val = -1
else:
fill_val = fill_values[col]
df[col] = df[col].fillna(fill_val).astype(typ)
return df
преобразовать в float (игнорируя ошибки), а затем преобразовать результат в int.
df['id'] = df['id'].astype(float, errors='ignore').astype(int)
кроме того:
df['id'] = df['id'].replace(np.nan,0)
а затем используйте регулярное выражение:
df['id'] = df['id'].astype(int)
в случае чисел, первоначально отформатированных как строки (например, " 35 " вместо 35), помогает следующее:
df['id'] = df['id'].apply(lambda x: int(x))
Сначала удалите строки, содержащие NaN. Затем выполните преобразование целых чисел в оставшихся строках. Наконец, снова вставьте удаленные строки. Надеюсь, это сработает
можно использовать .dropna()
если это нормально, чтобы удалить строки со значениями NaN.
df = df.dropna(subset=['id'])
в качестве альтернативы,
использовать .fillna()
и .astype()
заменить NaN значениями и преобразовать их в int.
я столкнулся с этой проблемой при обработке CSV-файла с большими целыми числами, в то время как некоторые из них отсутствовали (NaN). Использование float в качестве типа не было вариантом, потому что я мог потерять точность.
моим решением было использовать str в качестве промежуточного тип. Затем вы можете преобразовать строку в int, как вам будет угодно позже в коде. Я заменил NaN на 0, но вы можете выбрать любое значение.
df = pd.read_csv(filename, dtype={'id':str})
df["id"] = df["id"].fillna("0").astype(int)
для иллюстрации, вот пример того, как поплавки могут потерять точность:
s = "12345678901234567890"
f = float(s)
i = int(f)
i2 = int(s)
print (f, i, i2)
и выход:
1.2345678901234567e+19 12345678901234567168 12345678901234567890
в моем случае я отредактировал формат столбца csv, т. е. изменил формат столбца с общего на число.Тогда я могу изменить тип в панд.
df= pd.read_csv("data.csv")
df[['id']] = df[['id']].astype(int)