超级用户,
我有一个多索引数据框,如下所示:
DATA
DATETIME PLATFORM OBTYPE LONGITUDE LATITUDE PRESSURE
2014-12-01 GPSRO ba 164.87 -16.22 0.2086 -1.080487
-99.87 51.67 433.9650 9.404006
-99.84 51.66 447.1593 8.621209
-99.82 51.65 460.5582 9.060276
-99.78 51.63 474.2856 4.033578
-99.75 51.62 488.2451 -3.564176
-99.72 51.61 502.6438 2.418914
-99.71 51.60 517.6590 9.504872
-99.68 51.59 533.0165 2.074352
-99.63 51.57 548.5572 1.692488
-99.61 51.56 564.5204 1.287064
-99.58 51.55 581.1121 2.060976
... ...
-98.81 51.25 885.3300 1.078527
-98.79 51.24 911.0555 -6.613088
-98.66 51.20 936.2419 4.369489
-98.61 51.18 962.0027 4.806168
-98.60 51.17 989.4301 -9.383631
LATITUDE列的值介于-90到+90之间 LONGITUDE列的值为0到360 DATA列是观察到的纬度和经度
的观测值我想创建一个新的DataFrame,其中包含DATA的1-deg×1-deg平均值 新的DataFrame看起来像这样:
DATA
DATETIME PLATFORM OBTYPE LONGITUDE LATITUDE PRESSURE
2014-12-01 GPSRO ba 0.0 -89.50 0.2086 -1.080487
-88.50 474.2856 4.033578
-87.50 488.2451 -3.564176
... ...
1.0 -89.50 0.2086 -1.080487
-88.50 474.2856 4.033578
-87.50 488.2451 -3.564176
... ...
等等。
在熊猫中做到这一点的最佳和最有效的方法是什么?
由于
答案 0 :(得分:1)
您需要采取一些措施来实现这一目标:
np.floor
功能,因为它可以满足您的需要并保持简单。还具有矢量化的优点,因此性能应该是体面和稳定的。pandas
具有良好的groupby
功能(docs和more on the subject)。以下是我要做的事(免责声明:我还没有对其进行测试,因此可能需要进行一些调整):
import numpy as np
no_index_df = df.reset_index()
no_index_df['LONGITUDE'] = no_index_df['LONGITUDE'].apply(lambda x: [e for e in range(0, 361, longitude_bin) if e <= x][-1])
no_index_df['LATITUDE'] = no_index_df['LATITUDE'].apply(lambda x: [e for e in range(-90, 91, latitude_bin) if e <= x][-1])
avg_data = no_index_data.groupby(
['DATETIME', 'PLATFORM', 'OBTYPE', 'LONGITUDE', 'LATITUDE', 'PRESSURE']
).mean()
此方法的唯一问题是,对于同一(longitude, latitude)
对,您可能有多行,因为'PRESSURE'
上的聚合。你可以从groupby
列表中取出它,它也会被平均。
编辑:我改变了第1步(创建垃圾箱)让你使用任何间隔。
答案 1 :(得分:0)
除已接受的答案外:lambda函数非常慢。一旦有了几十万行和几十个仓,就可能需要几分钟来计算。我发现以下内容要快得多,而只需花费几秒钟:
import numpy as np
def find_nearest(value, array):
idx = (np.abs(array - value)).argmin()
return array[idx]
N_bins_long = 360
N_bins_lat = 180
longbins = np.linspace(df.LONGITUDE.min(), df.LONGITUDE.max(), N_bins_long)
latbins = np.linspace(df.LATITUDE.min(), df.LATITUDE.max(), N_bins_lat)
no_index_df = df.reset_index()
no_index_data.['LONGITUDE'] = no_index_data.['LONGITUDE'].apply(find_nearest, array = longbins)
no_index_data.['LATITUDE'] = no_index_data.['LATITUDE'].apply(find_nearest, array = latbins)
avg_data = no_index_data.groupby(
['DATETIME', 'PLATFORM', 'OBTYPE', 'LONGITUDE', 'LATITUDE', 'PRESSURE']
).mean()