Панды объединяются, разделяя значение каждый раз, когда оно объединяется

У меня есть 2 кадра данных из следующих

df :

     Name
1    A
2    B
3    C
4    C
5    D
6    D
7    D
8    D

и df_value :

     Name   Value
1    A      50
2    B      100
3    C      200
4    D      800

Я хочу объединить оба фрейма данных (в df), но новый Value стоит df_value Value, деленного на количество вхождений Name в df

Выход :

     Name   Value
1    A      50
2    B      100
3    C      100
4    C      100
5    D      200
6    D      200
7    D      200
8    D      200

A появляется один раз, имеет значение 50 в df_value, поэтому его значение равно 50. Та же логика для B. C появляется 2 раза, имеет значение 200 в df_value, поэтому его значение 200 / 2 = 100 D появляется 4 раза, имеет значение 800 в df_value, поэтому его значение 800 / 4 = 200.

Я почти уверен, что есть действительно простой способ сделать это, но я не могу его найти. Заранее спасибо.

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
3
0
114
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Используйте Series.map по столбцу Name и Series from df_value и разделите сопоставленные значения Series.value_counts:

df['Value'] = (df['Name'].map(df_value.set_index('Name')['Value'])
               .div(df['Name'].map(df['Name'].value_counts())))
print (df)
  Name  Value
1    A   50.0
2    B  100.0
3    C  100.0
4    C  100.0
5    D  200.0
6    D  200.0
7    D  200.0
8    D  200.0

Еще одно решение, спасибо @sammywemmy, — это сопоставление уже разделенных значений:

df1.assign(Value=df1.Name.map(df2.set_index("Name").Value.div(df1.Name.value_counts())))

Возможно решение с merge, также добавлена ​​альтернатива для подсчетов от GroupBy.transform:

df['Value'] = (df.merge(df_value, on='Name', how='left')['Value']
                 .div(df.groupby('Name')['Name'].transform('size')))

Альтернатива вашему решению: df1.assign(Value=df1.Name.map(df2.set_index("Name").Value.di‌​v(df1.Name.value_cou‌​nts())))

sammywemmy 22.12.2020 09:04

@sammywemmy - я запутался, для слияния с левым соединением сбрасывается индекс? Потому что я использую df.merge(df_value, on='Name', how='left') и индексирую не Int64Index([1, 2, 3, 4, 5, 6, 7, 8], dtype='int64'), а Int64Index([0, 1, 2, 3, 4, 5, 6, 7], dtype='int64'). Как вы думаете, это ошибка?

jezrael 22.12.2020 09:12

он отлично работает, когда я пробовал. Это дает мне Int64Index([1, 2, 3, 4, 5, 6, 7, 8], dtype='int64')

sammywemmy 22.12.2020 09:17

Я использовал 1-е решение, которое отлично работает, я думаю, что и другие. Большое спасибо за вашу помощь. Кстати, извините за то, что начал свой индекс с 1, это был неразумный ход с моей стороны -_-

Adept 22.12.2020 09:36

Если важно сохранить существующие кадры данных как есть и нет ограничений на использование двух строк кода:

df1 = df.merge(df_value, on='Name', how='left')
df1['Value'] = df1.groupby('Name')[['Value']].transform(lambda x: x/len(x))

В противном случае одно линейное решение, которое немного изменяет существующий 'df'.

df['Value'] = df.merge(df_value, on='Name', how='left').groupby('Name')[['Value']].transform(lambda x: x/len(x))

Оба дают одинаковый результат с разными именами переменных:

  Name  Value
0    A   50.0
1    B  100.0
2    C  100.0
3    C  100.0
4    D  200.0
5    D  200.0
6    D  200.0
7    D  200.0

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