#python #pandas
#python #pandas
Вопрос:
TL; DR: Я бы хотел изменить типы данных столбцов фрейма данных pandas на месте.
У меня есть фрейм данных pandas:
df = pd.DataFrame({'a': [1,2,3], 'b': [4,5,6.1]})
Которому по умолчанию присваиваются столбцы ‘int64’ и ‘float64’ в моей системе:
df.dtypes
Out[172]:
a int64
b float64
dtype: object
Поскольку мой фрейм данных будет очень большим, я хотел бы после создания фрейма данных установить для типов данных столбцов значения int32 и float32. Я знаю, как я мог бы это сделать:
df['a'] = df['a'].astype(np.int32)
df['b'] = df['b'].astype(np.float32)
или за один шаг:
df = df.astype({'a':np.int32, 'b':np.float32})
и dtypes моего фрейма данных действительно:
df.dtypes
Out[180]:
a int32
b float32
dtype: object
Однако: это кажется неуклюжим из-за необходимости переназначать series, особенно поскольку многие методы pandas имеют inplace
kwarg. Однако использование этого, похоже, не работает (начиная с того же фрейма данных вверху):
df['a'].astype(np.int32, inplace=True)
df.dtypes
Out[187]:
a int64
b float64
dtype: object
Есть ли что-то, что я здесь упускаю из виду? Это сделано специально? Такое же поведение проявляется при работе с объектами Series
вместо DataFrame
.
Большое спасибо,
Комментарии:
1. IMO inplace более неуклюжий, чем
df = df.astype({'a':np.int32, 'b':np.float32})
🙂2. Я не уверен, но я не думаю, что это было бы возможно.
3.
inplace
не имеет экономии памяти при переназначении вообще.4. Боюсь, что это невозможно сделать, похоже, pandas API pandas.pydata.org/pandas-docs/stable/reference/api / … не предлагает такой функции.
5. @coldspeed, речь идет не об экономии памяти, а о «потоке кода» и о том, как я думаю об объектах, которыми я манипулирую. «Исправление их» лучше соответствует изображению, чем «перезапись их новой версией самих себя». Кроме того, кажется странным решение иметь
inplace
опцию, доступную в некоторых, но не во всех операциях. И что еще более странно, он автоматически завершается сбоем, как это происходит в моем последнем примере.
Ответ №1:
Вы можете написать свои собственные (все еще неуклюжие) версии на месте:
def astype_inplace(df: pd.DataFrame, dct: Dict):
df[list(dct.keys())] = df.astype(dct)[list(dct.keys())]
def astype_per_column(df: pd.DataFrame, column: str, dtype):
df[column] = df[column].astype(dtype)
и используйте его как
astype_inplace(df, {'bool_col':'boolean'})
или
astype_per_column(df, 'bool_col', 'boolean')
Комментарии:
1. Привет, я получаю это в Google Colab «Ошибка имени: имя ‘Dict’ не определено» Вы знаете, откуда берется эта функция Dict? Заранее спасибо.
2. Я считаю, что это универсальный тип
typing.Dict
3. Все еще хорошо работает в 2022 году, просто добавьте «from typing import Dict», как было предложено.
Ответ №2:
А как насчет
>>> df.__dict__.update(df.astype({'a': np.int32, 'b': np.float32}).__dict__)
>>> df.dtypes
a int32
b float32
dtype: object
?
Ответ №3:
передайте имена столбцов и их тип данных в качестве словаря в качестве аргумента в .astype()
col_types = {'col_1':'type_1', 'col_4':'type_4'}
df = df.astype( col_types)
Это изменит тип данных только для тех столбцов, которые передаются через dictionary
Комментарии:
1. Это не приводит к изменению на месте.
Ответ №4:
@ElRudi
Когда я читаю-the-fine-manual: copy=False
может удовлетворить ваши потребности?
Комментарии:
1. На самом деле это не меняет тип ряда, содержащегося во фрейме данных, просто манипулирует его базовыми данными.