基于索引长度的多索引数据帧的返回切片(分层索引)

2024-04-25 05:57:14 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个数据帧fal_mean,其中多个索引是'lat''lon',和'yr'。下面只是数据片段,但我需要做的是根据给定lat/lon组合的索引'yer'(years)的条目数来选择数据。例如,我只想为每个lat和lon组合选择数据,其中有N个或更多条目(年数据),这样len(fal_mean['yr'] >= N)

lat lon yr        101      102        103        104     105     109                                                             
35  -75 1978   410.63   410.63   1231.890   4516.950    0.00    0.00   
        1979     0.00   406.05   4060.460   6090.690  406.05    0.00   
        1980  1441.89   720.94  11535.100  12256.050    0.00    0.00   
        1982   121.54     0.00    850.790      0.000    0.00    0.00   
        1983   638.82  2874.68  37272.955   1916.455    0.00  638.82   

'我可以根据lat和lon组合分别为我需要的任何列选择数据:

^{pr2}$

得到选择的长度:

^{3}$

但是我不知道如何使用
len(fal_mean.loc[(35, -75), '101']) > N

比如:

fal_mean.loc[(len(fal_mean.loc[(35, -75), '101']) > 32)] 

但我需要传递lat和lon指数的所有值。在


编辑1

这里有一个包含每个组合长度的数据框(index=lat,columns=lon),所以我只需要能够在origanl数据框的“fal_mean”上使用一些切片符号来调用这些组合

我用以下方法创建了数据帧:

cv=np.arange(35, 45, 1)
cv2=np.arange(-75, -66, 1)
fal=pd.DataFrame(data=None, index=cv, columns=cv2)
for lat in cv:
    for lon in cv2:
        fal.loc[lat, lon]=len(fal_mean.xs((lat, lon), level=('lat', 'lon')))

    -75 -74 -73 -72 -71 -70 -69 -68 -67
35  21  8   0   0   0   0   0   0   0
36  33  32  0   0   0   0   0   0   0
37  33  35  0   0   0   0   0   0   0
38  13  35  32  8   0   0   0   0   0
39  0   31  35  35  25  9   16  0   0
40  0   0   35  32  36  37  37  37  37
41  0   0   0   0   34  33  36  37  37
42  0   0   0   0   0   37  37  35  37
43  0   0   0   0   0   32  35  31  34
44  0   0   0   0   0   0   0   12  31

我希望有一些聪明的切片符号可以用来做这个。我试过xsdf.index.get_level_values,但我的语法错误。在

例如,fal_mean.loc[:, len(fal_mean.index.get_level_values('yr') >32)]不起作用。在

如果没有一种方法可以在一行中完成,我可以在这个矩阵上调用一个布尔数组,并希望使用.loc来调用原始数据帧中这些组合的0和1索引(lat,lon),但我还不确定如何实现这一点。在

fal >=32

    -75     -74     -73     -72     -71     -70     -69     -68     -67
35  False   False   False   False   False   False   False   False   False
36  True    True    False   False   False   False   False   False   False
37  True    True    False   False   False   False   False   False   False
38  False   True    True    False   False   False   False   False   False
39  False   False   True    True    False   False   False   False   False
40  False   False   True    True    True    True    True    True    True
41  False   False   False   False   True    True    True    True    True
42  False   False   False   False   False   True    True    True    True
43  False   False   False   False   False   True    True    False   True
44  False   False   False   False   False   False   False   False   False

编辑2: 这是前50行和4列,有28+列,但这一点并不重要。我想让所有的列只保留经纬度的组合,其中至少有(N)个条目用于年份索引-我认为32个可能就足够了。这将排除lat/lon组合(35,(all)),(36,-74),(38,-75)等的数据,并使用上面的数据帧作为指导。在

这些数据是由groupby函数grouped=nm.groupby(['lat', 'lon', 'yr'])生成的,所以如果我可以用一些限制来修改这个调用,从而得到分组.年这也会起作用。我尝试了df.groupby(['key1', 'key2', 'key3']).size(),这给出了每年每个lat lon组合的数据点的数量。在

                       101          102            103           104  
lat lon yr                                                             
35  -75 1978    410.630000   410.630000    1231.890000   4516.950000   
        1979      0.000000   406.050000    4060.460000   6090.690000   
        1980   1441.890000   720.940000   11535.100000  12256.050000   
        1982    121.540000     0.000000     850.790000      0.000000   
        1983    638.820000  2874.680000   37272.955000   1916.455000   
        1984   5419.645000   516.155000   12778.280000     96.990000   
        1985     99.836667     0.000000    2819.083333  13977.286667   
        1986   7113.757500  3909.402500   10313.850000   2823.675000   
        1987      0.000000   708.610000    6841.430000      0.000000   
        1988      0.000000     0.000000    4711.750000      0.000000   
        1997    408.410000   204.210000       0.000000      0.000000   
        1998    251.690000     0.000000   13507.510000      0.000000   
        2001    208.040000   485.420000   17474.970000      0.000000   
        2002      0.000000     0.000000    2173.193333      0.000000   
        2004      0.000000     0.000000       0.000000    465.480000   
        2005      0.000000     0.000000     231.600000      0.000000   
        2006      0.000000     0.000000    1209.420000      0.000000   
        2007      0.000000     0.000000       0.000000      0.000000   
        2009      0.000000     0.000000    3561.485000      0.000000   
        2010      0.000000     0.000000     347.500000      0.000000   
        2011      0.000000     0.000000    4742.660000      0.000000   
    -74 1994    908.000000   113.500000    1589.000000      0.000000   
        1996    231.960000     0.000000   55207.410000      0.000000   
        1999  18414.830000   575.460000  142139.500000    575.460000   
        2000      0.000000     0.000000   19388.510000    842.980000   
        2003   4654.030000     0.000000    2694.440000      0.000000   
        2005   6229.700000  1245.940000    8098.600000      0.000000   
        2006   3294.950000  6243.060000   14740.550000    346.840000   
        2013  19512.960000  9420.050000   10261.130000      0.000000   
36  -75 1977    426.498667   612.972667    5114.548667   6870.683333   
        1978    213.488571  1339.422857    7686.621429  12274.601429   
        1979    140.881333   536.751333    5403.046000   7349.630667   
        1980   3669.234667   552.227333   68924.586000   6117.865333   
        1981     24.875455   322.680909    6340.275455  22119.756364   
        1982   9261.615714  3890.987143   16226.872857    122.911429   
        1983    199.143333   478.403333   70658.200476    524.357143   
        1984   8193.242857   996.810714   43920.052143   3900.735714   
        1985    514.931364    23.260455    8051.927727    924.295909   
        1986   2884.836667  4156.231667   23677.898000   1393.353667   
        1987   2555.915417  2792.415000   25936.742917    833.030833   
        1988   1410.285000  1159.560000    7141.306667      0.000000   
        1993   6952.696667  9823.026667   64672.390000   5508.930000   
        1994    214.590000     0.000000  127691.851429   4720.532857   
        1995      0.000000     0.000000    3534.124000      0.000000   
        1996      0.000000     0.000000   63118.047500      0.000000   
        1997    175.766000   421.272000   23034.918000    527.300000   
        1998    105.652000     0.000000    2508.806000      0.000000   
        1999      0.000000     0.000000    1245.455000      0.000000   
        2000      0.000000     0.000000   10889.758000      0.000000   
        2001    948.245000   441.873750   27449.827500    138.930000   

Tags: 数据falsetrueindexlen条目meanlevel
2条回答

我不太清楚你的问题。 你想让所有的[lat,lon]组合都有超过30年的条目吗?在

如果是这样的话,你也许可以用

many_years = df[df.groupby(level=[0,1,2])['101'].count()>=30]

如果你能提供一个你的数据框架的最小例子,我可以试着更好的帮助,理想情况下我们可以通过pd.read_剪贴板()和你想要的结果。在

为了利益,我最后给出了一个解决方案。不,我没有找到一个优雅的单线解决方案,我不得不使用一个循环。但它能完成任务。在

# remove lat lon combinations where total sample years are less than Num
Num=32 # set criteria ~ 2014-1977 = 37 -5 ->32
def remove_N (nm, cv, cv2): # remove lat lon combinations where total sample years are less than N
    nm['id']=-1
    ll_index=0
    keep = list()
    for lat in cv:
        for lon in cv2:
            if len(nm.xs((lat, lon), level=('lat', 'lon'))) == 0:
                continue
            if len(nm.xs((lat, lon), level=('lat', 'lon'))) >= Num: # N
                keep.append(ll_index)
            t = nm.loc[lat,lon]
            t.id = ll_index
            ll_index = ll_index + 1
        data = nm.ix[nm ['id'].isin(keep)]
    data=data.drop('id', 1)
    return(data)

相关问题 更多 >