Учитывая этот образец:
df = pd.DataFrame(data=[(1, 'A', 5.0, 0.0),
(2, 'A', 3.0, 0.0),
(1, 'B', 1.0, 0.0),
(2, 'B', 2.0, 0.0),
(1, 'C', 6.0, 2.0)],
columns=('Date', 'Name', 'limit', 'allocation')).set_index(['Date','Name'])
groups = df.groupby('Date')
group = groups.get_group(1)
groupSorted = group.sort_values(by='limit', ascending=False)
Теперь groupSorted
выглядит так:
limit allocation
Date Name
1 C 6.0 2.0
A 5.0 0.0
B 1.0 0.0
Создав суб-DataFrame groupSorted
, Я хочу, чтобы формула set
allocation
в первой строке удовлетворяла условию, что allocation
равно 0. Как я могу это сделать?
Я нашел различные способы Выбрать первой строки с этим условием. Например.,
groupSorted[groupSorted.allocation == 0].iloc[0]
groupSorted[groupSorted.allocation == 0].head(1)
... и еще пути к получать и стоимость, которые я хочу изменить:
groupSorted[groupSorted.allocation == 0].iat[0, 1]
groupSorted[groupSorted.allocation == 0].iloc[0].at['allocation']
groupSorted[groupSorted.allocation == 0].iloc[0]['allocation']
groupSorted[groupSorted.allocation == 0]['allocation'].iat[0]
Но ни один из них не позволяет мне задавать это значение. Как я могу установить это значение, чтобы оно «застряло» в оригинале group
и df
?
@noah: Если я вношу изменения в group
, они применяются к родителю df
. К тому времени, когда я изменяю groupSorted
, я не уверен .... Таким образом, установка значения в группе сортированный, кондиционированный является частью проблемы.
Я думаю, ты хочешь groupSorted.loc[groupSorted['allocation'] == 0, 'allocation'].values[0] = 12345
@ cs95: я пробовал это, но это ничего не меняет в groupSorted
. Если я это сделаю groupSorted.loc[groupSorted['allocation'] == 0, 'allocation'].iloc[0] = 123
, я, по крайней мере, получу SettingWithCopyWarning
....
Меня устраивает. Вы также можете попробовать groupSorted.loc[(groupSorted['allocation'] == 0).idxmax(), 'allocation'] = 12345
И если это не сработает, проблема, скорее всего, не в коде.
Второй вариант — с использованием .idxmax()
— работает! Но это не влияет на предварительно отсортированные group
или df
. Есть ли способ изменить эту строку в исходном фрейме данных?
Панды были разработаны, чтобы избежать подобных «побочных эффектов». НастройкаWithCopyWarning является хорошим примером этого. Если вы хотите изменить исходную группу, вам нужно будет вызвать df.update(groupSorted)
, чтобы сохранить ее. Это лучший совет, который я могу дать.
@ cs95, это должно работать, но я был бы признателен за любой ответ, который дает пандалитический способ сделать это, который будет эффективно масштабироваться с количеством строк и групп. (Я хочу применить эту логику рекурсивно к группам в корневом фрейме данных.)
Из комментариев к вопросу:
Чтобы присвоить groupSorted
, мы можем использовать:
groupSorted.loc[(groupSorted['allocation'] == 0).idxmax(), 'allocation'] = 123
Чтобы получить назначение «прилипнуть» к исходному DataFrame, мы можем сделать:
df.at[(groupSorted['allocation'] == 0).idxmax()] = 123
Вы уверены, что при внесении изменений вы изменяете их на месте, а не создаете новый df?