我正在尝试使用一个接受两个输入元组的自定义函数将一个新列映射到pandas数据帧。功能是:
def distance(origin, destination):
lat1, lon1 = origin
lat2, lon2 = destination
radius = 3958.8 # miles
dlat = math.radians(lat2-lat1)
dlon = math.radians(lon2-lon1)
a = math.sin(dlat/2) * math.sin(dlat/2) + math.cos(math.radians(lat1))
* math.cos(math.radians(lat2)) * math.sin(dlon/2) * math.sin(dlon/2)
c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a))
d = radius * c
return d
数据帧有一列元组形式的lat和long,我正试图测量当前行和前一行坐标之间的距离。
我尝试了一个for循环:
df3.loc[0, 'dist'] = 0
for i in range(1, len(df3)):
df3.loc[i, 'dist'] = distance(df3.loc[i-1, 'lat_long'], df3.loc[i, 'lat_long'])
但是我得到了一个错误";ValueError:没有足够的值来解包(应为2,得到1(";
关于如何做得更好,有什么想法吗?
综合数据说明
reset_index()
以获取行号作为列index
- 构造从前一行到当前行的CCD_ 3。如果前一行是第一行,则将其浮动为0
- 将元组列表传递给CCD_ 4。你注意到你的长lat是元组
- 显示将当前行和前一行考虑在内的计算
- 最终去除合成
index
柱
df = pd.DataFrame({"geo":[(1,2),(3,4),(5,6)]}).reset_index()
def distance(prev, curr):
return prev[0] + prev[1] + curr[0] + curr[1]
def tuplecalc(tuples):
return distance(tuples[0], tuples[1] if len(tuples)==2 else (0,0))
df["distance"] = df.apply(lambda r: tuplecalc(df.loc[range(max(r["index"]-1,0),r["index"]+1),"geo"].values), axis=1)
df.drop(["index"], axis=1)
作为附加列
df = pd.DataFrame({"long":[1,3,5], "lat":[2,4,6]}).reset_index()
def rowrange(index, col):
return 0 if index==0 else df.loc[range(max(index-1,0),index), col].values[0]
df["prev_long"] = df.apply(lambda r: rowrange(r["index"], "long"), axis=1)
df["prev_lat"] = df.apply(lambda r: rowrange(r["index"], "lat"), axis=1)
df
输出
geo distance
0 (1, 2) 3
1 (3, 4) 10
2 (5, 6) 18