多索引Pandas DataFrame中的顺序排序

时间:2016-05-17 15:32:11

标签: python sorting pandas set

我有一个数字值的多索引Pandas数据帧。我希望使用数据的另外两个子集按顺序对数据帧的子集中的每一行进行排序。我相信下面的例子可以更好地说明我的需求:

考虑这个示例数据集:

                         A          B          C          D
rtr  2015-01-31  -1.085631  -0.204201   1.730024   1.710438
     2015-02-28   0.997345   1.979348   1.232650  -0.056341
key1 2015-01-31   6.180000   0.990000   2.440000   1.920000
     2015-02-28   1.140000   1.810000   4.560000   0.740000
key2 2015-01-31  86.000000  36.000000  61.000000  34.000000
     2015-02-28  97.000000  96.000000  48.000000  98.000000

考虑日期key1下的key2rtr2015-02-28的最后一行:

  1. df.loc['key1']中,获取2个最大值的列名。 (即:C,B)
  2. 从列空间中排除C和B列。 (即:cols剩余:A,D)
  3. df.loc['key2']中,获取剩余列空间中最大值的列名。 (即:A列和D列中的值,D更大 - >返回D)
  4. df.loc['rtr']中获取与步骤1和3中找到的列名对应的相应值(即:返回值df.loc['rtr'].loc['20150228',['C','B','D']]
  5. In [140]: df.loc['rtr'].loc['20150228',['C','B','D']]
    Out[140]:
    C    1.232650
    B    1.979348
    D   -0.056341
    Name: 2015-02-28 00:00:00, dtype: float64
    

    示例数据生成代码:

    ## generate data:
    d1,d2,d3 = {},{},{}
    np.random.seed(123)
    for col in list("ABCD"):
        d1[col] = np.random.randn(2)
        d2[col] = np.random.gamma(2,3,2).round(2)
        d3[col] = np.random.random_integers(0,100, 2)
    t_index = pd.date_range(start = '2015-01-31', periods = 2, freq = "M")
    
    dat1 = pd.DataFrame(d1, index = t_index)
    dat2 = pd.DataFrame(d2, index = t_index)
    dat3 = pd.DataFrame(d3, index = t_index)
    
    df = pd.concat([dat1, dat2, dat3], keys = ['rtr', 'key1', 'key2'])
    

1 个答案:

答案 0 :(得分:1)

第1步:解决给定日期的问题。

df1 = df.xs('2015-01-31', level=1)

columns = df1.loc['key1'].nlargest(2).index.tolist()
columns.append(df1.loc['key2'][df.columns.difference(columns)].idxmax())
df1.loc['rtr', columns]

我们使用nlargest并获取结果的索引,因为idxmax仅适用于一个最大值。在使用pandas'排除之前的列之后,我们在以下行中使用idxmax index difference方法。

第2步:使用groupby将上述解决方案分别应用于每个日期。

def func(df2):
    df1 = df2.reset_index(level=1, drop=True)
    columns = df1.loc['key1'].nlargest(2).index.tolist()
    columns.append(df1.loc['key2'][df.columns.difference(columns)].idxmax())
    return df1.loc['rtr', columns]

df.groupby(level=1).apply(func)

添加了reset_index,因为与xs相比,groupby不会降低索引级别。