Обновить значения в df после groupby И get_group

У меня есть фрейм данных в форме

df = pd.DataFrame({'dim_unit' :['m', 'cm', 'cm', 'm', 'ft', 'in'], 'Length' : [1,2,3,4,5,6], 'Width' : [5,6,7,8,9,10] }) 

Я пытаюсь использовать groupby для группировки по разным единицам измерения, а затем, беря подфрейм данных, применяю коэффициент масштабирования к каждому столбцу «Длина» и «Ширина», чтобы результирующий фрейм данных имел одинаковые размеры. (На самом деле больше единиц измерения и столбцов для транспонирования).

Следующее работает, за исключением того, что я не могу заставить его обновить его в исходном фрейме данных (очевидно, повторяя еще раз для «Высоты», «м» и т. д.).

g= df.groupby('dim_unit')

g.get_group('cm')[["Width"]].apply( lambda x: x*100)

Я пробовал использовать преобразование вместо применения, но это ничего не изменило. я тоже пробовал

df['len_cm_to_m']= df.get_group('cm')[["Width"]].apply( lambda x: x*100)

Но в результате получается столбец с большим количеством Nan, и тогда мне пришлось бы повторить для каждого из см, дюймов, футов и т. д. и объединить значения в один столбец преобразованных единиц. В частности, поскольку существует около 5 различных типов единиц, по которым я группирую, и каждая из функций применения будет отличаться для каждой единицы, а затем для нескольких столбцов, над которыми я работаю, это создаст 15 новых столбцов для всего моего набора данных. с множеством значений Nan, которые мне затем нужно было бы объединить, и это выглядит как беспорядок.

Итак, есть ли способ обновить значения в df из полученной функции Apply? В идеале это было бы обновление значений. Или я также думал о том, чтобы попытаться использовать слияние (или подобное) для обновления столбца путем сопоставления индексов?

Любые советы по этому поводу очень ценятся!

Вы пытаетесь перезаписать существующие записи? Добавить новые?

shadowtalker 10.10.2023 03:47

Перезаписать существующий. Хотя, если бы это привело к созданию ОДНОГО нового столбца для каждой длины и высоты, это было бы нормально. Проблема с новым столбцом заключается в том, что мне нужно создать его для высоты (или длины) каждого «м», «см», «дюйма» и т. д.

Elise 10.10.2023 16:07

Обратите внимание, что .groupby во втором фрагменте кода на самом деле ничего не делает. Вызов .groupby для фрейма данных не выполняет операцию над данными на месте. Он создает новый сгруппированный фрейм данных, который вы отбрасываете, не назначая какой-либо переменной. Если вы попытаетесь запустить код как написано, вы получите ошибку: AttributeError: 'DataFrame' object has no attribute 'get_group'.

shadowtalker 10.10.2023 18:03

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

Elise 12.10.2023 19:22

Я еще ничего не говорил о присвоении результата... просто код, который вы выложили, даже не работает.

shadowtalker 12.10.2023 20:29
1
5
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вам не нужно группировать, вы можете просто map привести единицы к шкале, а затем умножить:

# convert all the units to cm
conversion_dict = {
    "m": 100,
    "cm": 1,
    "ft": 12 * 2.54,
    "in": 2.54
}

df[['Length','Width']] = df[['Length','Width']].mul(df['dim_unit'].map(conversion_dict), axis=0)

Выход:

  dim_unit  Length   Width
0        m  100.00  500.00
1       cm    2.00    6.00
2       cm    3.00    7.00
3        m  400.00  800.00
4       ft  152.40  274.32
5       in   15.24   25.40

Примечание. Вместо этого может быть лучше/яснее использовать новые столбцы:

df[['Length_cm','Width_cm']] = df[['Length','Width']].mul(df['dim_unit'].map(conversion_dict), axis=0)

И у вас будет:

  dim_unit  Length  Width  Length_cm  Width_cm
0        m       1      5     100.00    500.00
1       cm       2      6       2.00      6.00
2       cm       3      7       3.00      7.00
3        m       4      8     400.00    800.00
4       ft       5      9     152.40    274.32
5       in       6     10      15.24     25.40

Спасибо, это делает то, что я хочу. Единственная проблема заключается в том, что выдается следующее предупреждение: «Значение пытается быть установлено в копии среза из DataFrame. Попробуйте вместо этого использовать .loc[row_indexer,col_indexer] = value». См. предостережения в документации: ️ 🔁 pandas.pydata.org/pandas-docs/stable/user_guide/… "

Elise 10.10.2023 16:38

@Элиза, в какой-то момент ваш df был создан путем вырезания/выбора строк из более крупного фрейма данных. В целях эффективности Pandas не копирует данные при этом. Вот о чем говорит предупреждение: вы делаете то, чего, вероятно, не хотели делать.

shadowtalker 10.10.2023 18:01

Другие вопросы по теме