我有一个经度值的数组(lons),范围是[-180,180]。我需要找到时间序列的平均值。这很容易用
完成np.mean(lons)
如果系列包含日期线两侧的值,那么这种直截了当的意思当然不起作用。计算所有可能情况的平均值的正确方法是什么?请注意,我宁愿没有条件以不同方式处理日期线交叉案例。
在从度数转换为rad之后,我已经使用过np.unwrap,但我知道我的计算是错误的,因为一小部分案例给出了我在非洲0度(经线)附近的平均经度。这些都是不可能的,因为这是一个海洋数据集。
感谢。
编辑:我现在意识到计算时间序列的平均[lat,lon]位置的更精确方法可能是转换为笛卡尔网格。我可以走这条路。
答案 0 :(得分:0)
这是directional statistics的应用程序,其中角平均值是在复平面中计算的(参见this section)。结果是一个复数,其虚部表示平均角:
import numpy as np
def angular_mean(angles_deg):
N = len(angles_deg)
mean_c = 1.0 / N * np.sum(np.exp(1j * angles_deg * np.pi/180.0))
return np.angle(mean_c, deg=True)
lons = [
np.array([-175, -170, 170, 175]), # broad distribution
np.random.rand(1000) # narrow distribution
]
for lon in lons:
print angular_mean(lon), np.mean(lon)
正如您所看到的,算术平均值和角度平均值对于窄分布非常相似,而它们在广泛分布时显着不同。
使用笛卡尔坐标是不合适的,因为质心将位于地球内,但由于您使用的是表面数据,我假设您希望它位于表面上。
答案 1 :(得分:0)
这是我的解决方案。请注意,我计算平均纬度和经度,以及计算平均纬度(lat_mean)和平均经度(lon_mean)的[lat,lon]坐标的平均距离(mean_dist)。原因是我也对中央[lat,lon]的变化感兴趣。我相信这是正确的,但我愿意讨论!
lat_size = np.size(lats)
lon_rad = np.deg2rad(lons) # lons in degrees [-180, 180]
lat_rad = np.deg2rad(lats) # lats in degrees [-90, 90]
R = 6371 # Approx radius of Earth (km)
x = R * np.cos(lat_rad) * np.cos(lon_rad)
y = R * np.cos(lat_rad) * np.sin(lon_rad)
z = R * np.sin(lat_rad)
x_mean = np.mean(x)
y_mean = np.mean(y)
z_mean = np.mean(z)
lat_mean = np.rad2deg(np.arcsin(z_mean / R))
lon_mean = np.rad2deg(np.arctan2(y_mean, x_mean))
# Calculate distance from centre point for each [lat, lon] pair
dist_list = np.empty(lat_size)
dist_list.fill(np.nan)
p = 0
for lat, lon in zip(lats, lons):
coords_1 = (lat, lon)
coords_2 = (lat_mean, lon_mean )
dist_list[p] = geopy.distance.vincenty(coords_1, coords_2).km
p = p + 1
mean_dist = np.mean(dist_list)
return lat_mean, lon_mean, mean_dist