Измените тип столбца pandas series / dataframe на месте

#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 может удовлетворить ваши потребности?

https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas .DataFrame.astype.html ?выделить =тип #pandas.DataFrame.astype

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

1. На самом деле это не меняет тип ряда, содержащегося во фрейме данных, просто манипулирует его базовыми данными.