数据框:如何为每一行选择不同的列

时间:2018-12-20 17:05:52

标签: python pandas dataframe

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

最简单的示例如下:

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]

那行得通,但是在我的真正问题中,我使用了多索引的Dataframe,事情变得更加复杂。

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

我想到的第一件事是:

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

有效!

1 个答案:

答案 0 :(得分:2)

您可以使用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])