我有两个数据框df1
和df2
。 df1
包含共享相同人口的两个地方之间的信息。
df1
PlaceA Population PlaceB
0 3 10 2
1 4 10 2
2 7 17 0
3 9 13 1
df2
包含到达PlaceB
的行进距离
df2
PlaceB distance
0 0 130
1 1 145
2 2 165
我希望有一个在df1
上合并df2
和PlaceB
的数据框,然后返回人口除以共享同一人口的地点数。例如,地点2、3、4共享相同的人口,我们除以3。
df3
Place Population Distance
0 0 17/2 130
1 1 13/2 145
2 2 10/3 165
3 3 10/3 165
4 4 10/3 165
5 7 17/2 130
6 9 12/2 145
答案 0 :(得分:1)
您可以尝试:
PlaceB
上的两个数据帧与outer
合并,以确保考虑所有PlaceB
的值。 merge
函数可以完成这项工作。groupby
按placeB
分组。对于每个组:
3.1。使用melt
将PlaceA
和PlaceB
列转换为一列(称为Place
)。
3.2。使用drop_duplicates
删除重复项 3.3。将Population
列转换为所需的输出。在这里,我将其转换为字符串以匹配所需的输出。
可选(以匹配所需的输出):
用Place
和sort_values
对值进行排序。
使用drop
使用reset_index
重置并删除当前索引。
代码在这里:
# Import module
import pandas as pd
# The input data
df1 = pd.DataFrame({"PlaceA": [3, 4, 7, 9],
"Population": [10, 10, 17, 13],
"PlaceB": [2, 2, 0, 1]})
df2 = pd.DataFrame({"PlaceB": [0, 1, 2], "distance": [130, 145, 165]})
# Function to apply to each `PlaceB` group
def melt_and_pop_up(x):
x = x.melt(id_vars=['Population', 'distance'], value_name='Place') \
.drop_duplicates()
x.Population = "{}/{}".format(x.Population.values[0], len(x))
# Get decimal values
# x.Population = x.Population.values[0] / len(x)
return x
df = df1.merge(df2, on="PlaceB", how='outer') \
.groupby('PlaceB') \
.apply(melt_and_pop_up) \
.sort_values('Place') \
.drop(columns=['variable']) \
.reset_index(drop=True) \
[["Place", "Population", "distance"]]
print(df)
# Place Population distance
# 0 0 17/2 130
# 1 1 13/2 145
# 2 2 10/3 165
# 3 3 10/3 165
# 4 4 10/3 165
# 5 7 17/2 130
# 6 9 13/2 145
答案 1 :(得分:0)
我创建了一个自定义函数,并使用lambda对其进行了调用。基本上按人口分组,然后按地点A和地点B中的唯一元素进行划分。
df1= pd.DataFrame({"PLaceA":[3,4,7,9], "Population": [10,10,17,13], "PlaceB":
[2,2,0,1]})
df2 = pd.DataFrame({"PlaceB":[0,1,2], "distance": [130,145,165]})
df3 = df1.merge(df2, on= "PlaceB", how= "left")
def find_unique(a,b,p):
t = p.tolist()[0]
r = t/(len(a.unique())+len(b.unique()))
return r
df4 = df3.groupby(['Population']).apply(lambda x: find_unique(x["PLaceA"],
x["PlaceB"], x["Population"])).reset_index()
df3=df3.merge(df4, on ="Population", how="left").rename( columns =
{0:"newpop"})
df5 = df3[['PLaceA','newpop']].drop_duplicates().rename(columns ={'PLaceA':
'Place', 'newpop':"Population"})
df6 = df3[['PlaceB','newpop']].drop_duplicates().rename(columns ={'PlaceB':
'Place', 'newpop':"Population"})
final_df = pd.concat([df5,df6])