我有两个数据帧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
你可以试试:
将PlaceB
上的两个数据帧与outer
合并,以确保考虑所有PlaceB
值。merge
函数完成这项工作。- 使用
groupby
按placeB
分组。 对于每个组:
3.1. 使用
melt
将PlaceA
和PlaceB
列转换为一列(称为Place
(。3.2. 使用drop_duplicates删除重复项
3.3. 将
Population
列转换为所需的输出。在这里,我将其转换为字符串以匹配所需的输出。
可选(匹配所需的输出(:
使用
sort_values
按Place
对值进行排序。使用
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
我创建了一个自定义函数并使用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])