【问题标题】:Sequential sorting in multi-indexed Pandas DataFrame多索引 Pandas DataFrame 中的顺序排序
【发布时间】:2016-05-17 15:32:10
【问题描述】:

我有一个多索引的 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

考虑key1key2rtr在日期2015-02-28下的最后一行:

  1. df.loc['key1']中,获取2个最大值的列名。 (即:C、B)
  2. 从列空间中排除 C 和 B 列。 (即:剩余列数:A,D)
  3. df.loc['key2']中,获取剩余列空间中最大值的列名。 (即:在 A 和 D 列中的值中,D 较大 -> 返回 D)
  4. df.loc['rtr']获取对应于步骤1和3中找到的列名的值(即:返回值df.loc['rtr'].loc['20150228',['C','B','D']]
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'])

【问题讨论】:

  • 还不清楚你想要什么。
  • 嗨伙计,你能澄清一下哪些部分不清楚吗?
  • 您在仅用于2015-01-31 的样本数据上应用了星号。这将有助于更好地理解预期输出的样子。当我看到需要回答的问题时,我会判断我认为我需要多长时间才能回答这个问题。然后我会用我目前的工作量来平衡这个。最后,如果我在阅读问题时眼睛发呆,我会跳过它。让他人尽可能轻松地阅读和理解,这符合您的最大利益。
  • 我希望我解决了您提到的问题并重新格式化了问题以使其更短。感谢您指出问题。

标签: python sorting pandas set


【解决方案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 最多只能工作一个。我们在下面的行中使用idxmax,在排除了具有pandas索引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 不会降低索引级别。

【讨论】:

  • 优秀的解决方案!我可能会决定在第二步中使用nlargest(m).index.tolist(),因为这旨在推广到更大的数据集和每个键的多个选择。我从没想过要使用groupby,因为我一直在与np.argsortdf.apply 作斗争。感谢您的代码!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-29
  • 2013-06-19
  • 2018-07-28
  • 2021-01-07
  • 2018-06-18
相关资源
最近更新 更多