【问题标题】:locate conditional column value based on row max根据最大行定位条件列值
【发布时间】:2018-02-03 09:42:04
【问题描述】:

这是一个更大的df_data 1000 x 150 的简单版本

Date            A   B   C   D        A'  B' C'  D'
31/01/2017      47  15  45  40       10  7  12   8
28/02/2017      22  34  28  13        3  2  26   4
31/03/2017      25  12  13  47        1  5   6  59

基本问题是需要对 A、B、C、D 列进行行排序,并使用最大/最小标准来定位 A'、B'、C'、D' 列中的相应行值

需要关注。

(1) 找出每个日期(行)的 n 个最大值和 n 个最小值。 让我们在这里假设n = 2。 (2) 以 (1) 中的最小值/最大值为条件,使用相关的列标题在同一行中为 A',B,C',D' 中的不同列找到相应的值 (在相同的 df 或不同的 df 中具有完全相同的日期索引)

假设 A,B,C,D 和 A',B',C',D' 之间存在 1-1 映射)

想要的结果:

31/01/2017: max1 = 10, max2 =12 ; min1 = 7, min2 = 8
28/02/2017: max1 =  2, max2 =26 ; min1 = 4, min2 = 3
31/03/2017: max1 = 59, max2 = 1 ; min1 = 5, min2 = 6

我可以找到例如使用的最大值

df_data [["A","B","C","D"]].apply(lambda row: np.max(row),axis=1)

但是如何在.apply 中使用iloc 函数或其他方式来查找该最大值的col 标头(索引)? (我在numpy 数组中尝试了.argsort,但无法到达任何地方)

另外,如何使用ranksort 在每行中找到顶部n 和底部n 值(其中n > 1)?我尝试按照以下方式对行进行排序(降序)

df_data.values.sort
df_data = df_data.iloc[:,::-1]

这似乎可行,但我的最终目标是找到列 A'、B'、C'、D' 中的值

如果有点长,请见谅。

【问题讨论】:

    标签: python pandas sorting dataframe row


    【解决方案1】:

    我用Numpy Fancy Indexing

    第一步是确定ABCD 列中最大元素的索引。 np.argmax 可以,但你提到你想找到最小的、第二大的、第二小的等等。所以使用np.argsort

    >>> idxs = df['A B C D'.split()].apply(np.argsort, axis=1).values
    

    在您的示例中,idxs 是:

    array([[1, 3, 2, 0],
           [3, 0, 2, 1],
           [1, 2, 0, 3]], dtype=int64)
    

    idxs的第一列是ABCD各列中最小元素的索引。也就是说,df.iloc[0, 1] 是 15,第一行中的最小元素。 df.iloc[1, 3] 是 13,第二行中的最小元素。等等。idxs 的第二列是第二小的索引。 idxs 的最后一列是最大元素的索引。

    我们使用它来对A'B'C'D' 列进行 Numpy Fancy 索引。为此,我们使用两个数组来为二维数组下标。第一个数组是行索引,第二个数组是每行所需的列。

    >>> df[["A'", "B'", "C'", "D'"]].values[np.arange(nrow), idxs[:, -1]]
    

    由于我们使用idxs 的最后一列,我们从A'B' 列中选择ABCD 列中最大项的索引,C'D'。所以结果是

    array(['10', '2', '59'], dtype=object)
    

    根据需要。

    选择最小使用对应的元素

    >>> df[["A'", "B'", "C'", "D'"]].values[np.arange(nrow), idxs[:, 0]]
    array(['7', '4', '5'], dtype=object)
    

    【讨论】:

    • 感谢 meta4。请回答 2 个问题 - 上面的 array(['10', '2', '59'], dtype=object) 是一维数组。我的 df 中的所有行都需要这个数组。我尝试 for i in range(-bot_n,top_n): idxs2 = df2.values[np.arange(nrow), idxs[:, i]] 如何填充 idxs2 (2D) 以包含所有行的所有数组?还是更容易写到df?抱歉,我是 np 数组和 df 的新手
    • 第二个问题:我创建了 2 个 dfs - 一个用于 A B C D ,另一个用于 A' B' C' D'...因为我有很多列我试图删除 .拆分并执行以下操作: idxs = df.apply(np.argsort, axis=1) idxs2 = df2.values[np.arange(nrow), idxs[:, i]]1).values 有没有更好的方法?发送
    • 我不确定我能否在这里回答您的所有问题。我建议查看np.argsort 的文档。 idxs 数组的内容是你需要找到 A B C D 等的最小、最大、第二小、第二大等元素所需的所有信息。不管 A' B' C' D'在同一个 DataFrame 或不同的 DataFrame 中。
    • 谢谢。我让它工作了。我想将 A' B' C' D' 中的行映射到带有偏移量的 A B C D - 在下面的代码中,我使用“滞后”作为偏移量。不确定是否有一个简单的功能可以像我用蛮力做的一样?对于范围内的 i(lag,nrow): 对于范围内的 j (ncol): c= (idxs[i-lag,j]) df_rankRet.iloc[i-lag,j]=df_ret.iloc[i,c]
    猜你喜欢
    • 2021-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-02
    • 1970-01-01
    • 2015-11-04
    • 2012-09-30
    • 1970-01-01
    相关资源
    最近更新 更多