通过比较当前和上一行元组将新列映射到 Pandas 数据框
Map a new column to a Pandas dataframe by comparing current and previous row of tuples
我正在尝试使用接受两个输入元组的自定义函数将新列映射到 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
数据框有一列元组形式的纬度和经度,我正在尝试测量当前行和上一行坐标之间的距离。
我试过 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
- 构造一个从前一行到当前行的
range()
。如果是第一行,则将前一行设为 0
- 将元组列表传递给
tuplecalc()
。你注意到你的 long,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
我正在尝试使用接受两个输入元组的自定义函数将新列映射到 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
数据框有一列元组形式的纬度和经度,我正在尝试测量当前行和上一行坐标之间的距离。
我试过 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
- 构造一个从前一行到当前行的
range()
。如果是第一行,则将前一行设为 0 - 将元组列表传递给
tuplecalc()
。你注意到你的 long,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