【问题标题】:Dataframe: How to select for each row different column数据框:如何为每一行选择不同的列
【发布时间】:2018-12-21 01:34:33
【问题描述】:

让我们考虑一个包含三列的数据框 A:a、b 和 c。假设我们还有与 A 大小相同的系列 B。在每一行中,它包含 A 列之一的名称。我想构造一个系列,它将包含表 A 中 B 指定的列中的值。

最简单的例子如下:

idxs = np.arange(0, 5)
A = pd.DataFrame({
    'a': [3, 1, 5, 7, 8],
    'b': [5, 6, 7, 3, 1],
    'c': [2, 7, 8, 2, 1],
}, index=idxs)
B = pd.Series(['b', 'c', 'c', 'a', 'a'], index=idxs)

我需要应用一些操作,其结果与以下系列相同:

C = pd.Series([5, 7, 8, 7, 8], index=idxs)

在这样一个简单的例子中,可以在纯 numpy 数组上执行如下“广播”:

d = {'a':0, 'b':1, 'c':2 }
AA = A.rename(columns=d).as_matrix()
BB = B.apply(lambda x: d[x]).as_matrix()

CC = AA[idxs, BB]

这行得通,但在我的真正问题中,我有多重索引数据框,事情变得更加复杂。

是否可以使用 pandas 工具来做到这一点?

我首先想到的是:

A['idx'] = B;
C = A.apply(lambda x: x[x['idx']], axis=1)

有效!

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    你可以使用DataFrame.lookup:

    pd.Series(A.lookup(B.index, B), index=B.index)
    
    0    5
    1    7
    2    8
    3    7
    4    8
    dtype: int64
    

    涉及广播的 NumPy 解决方案是:

    A.values[B.index, (A.columns.values == B[:, None]).argmax(1)]
    # array([5, 7, 8, 7, 8])
    

    【讨论】:

    • 谢谢,这正是我想要的!
    猜你喜欢
    • 1970-01-01
    • 2019-01-18
    • 2012-10-20
    • 1970-01-01
    • 1970-01-01
    • 2012-11-08
    • 2020-06-16
    • 1970-01-01
    • 2017-06-22
    相关资源
    最近更新 更多