使用pandas在2D中平均地理数据

时间:2016-05-01 18:52:57

标签: python pandas

超级用户,

我有一个多索引数据框,如下所示:

                                                        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
...                                                          ...

等等。

在熊猫中做到这一点的最佳和最有效的方法是什么?

由于

2 个答案:

答案 0 :(得分:1)

您需要采取一些措施来实现这一目标:

  1. 创建您的垃圾箱,我在这里使用np.floor功能,因为它可以满足您的需要并保持简单。还具有矢量化的优点,因此性能应该是体面和稳定的。
  2. 通过取平均值来聚合这些箱子。为此,pandas具有良好的groupby功能(docsmore on the subject)。
  3. 以下是我要做的事(免责声明:我还没有对其进行测试,因此可能需要进行一些调整):

    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()