我有来自以下的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
值为Value
除以df
中Name
的出现次数
输出:
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出现一次,在df_value
中的值为50,因此其值为50。B的逻辑相同。C出现2次,在df_value
中的值为200,因此其值为200/2=100D出现4次,在df_value
中的值为800,因此其值为800/4=200
我确信有一种非常简单的方法可以做到这一点,但我找不到。提前谢谢。
使用Series.map
乘以Name
列和来自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')))
如果保持现有数据帧原样很重要,并且不限制使用2行代码:
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