You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何高效按行索引从numpy数组或pandas DataFrame取值?

Efficient Vectorized Solution for Column-Wise Index Extraction

Great question! The problem with using np.take directly is that it operates on the flattened version of your array, not applying the index to each column individually. We can fix this with numpy's broadcasting and reshaping capabilities to create a fully vectorized solution—no loops needed, and it’ll be way faster for larger datasets.

Method 1: np.take with Dimension Expansion

This is the most concise approach. We’ll add an extra dimension to the original array so take can apply the index to each column separately, then reshape the result to your target shape:

import numpy as np

arr = np.asarray([[0, 1, 2, 4], [1, 2, 3, 4], [2, 3, 4, 5]])
indices = np.asarray([[-1, 0, 1], [-1, -1, 0]]).T

# Add a third dimension to arr (shape becomes (3,4,1))
arr_expanded = arr[:, :, np.newaxis]
# Apply indices to the row axis (axis=0) for each column
temp_result = arr_expanded.take(indices, axis=0)
# Reshape to (3, 4*2) by flattening the last two dimensions
res_efficient = temp_result.reshape(arr.shape[0], -1)

print(f"efficient result:\n{res_efficient}")

Output

efficient result:
[[2 2 3 3 4 4 5 5]
 [0 2 1 3 2 4 4 5]
 [1 0 2 1 3 2 4 4]]

How It Works

  • arr[:, :, np.newaxis] turns your (3,4) array into (3,4,1), treating each column as a separate "slice" along the new third dimension.
  • take(indices, axis=0) applies the index array to each of these slices, resulting in a (3,4,2) array—each original column now has 2 columns from the index lookup.
  • reshape(arr.shape[0], -1) flattens the last two dimensions into one, giving you the desired (3,8) shape.

Method 2: Advanced Indexing

If you prefer using numpy’s advanced indexing syntax, you can explicitly construct row and column index arrays to target the exact elements you need:

# Create row indices (shape: (3,1,1))
rows = np.arange(arr.shape[0])[:, None, None]
# Create column indices (shape: (1,4,1))
cols = np.arange(arr.shape[1])[None, :, None]
# Use broadcasting to match dimensions and select elements
res_advanced = arr[rows, cols, indices[:, None, :]].reshape(arr.shape[0], -1)

This achieves the same result as Method 1, using explicit index matching instead of take.

Performance Benefits

Vectorized operations like these are drastically faster than looping, especially as your dataset grows. For example, if you have an array with 1000 rows and 1000 columns, the loop approach would run 1000 separate take calls, while the vectorized method does it in one step—you’ll see a difference of seconds vs. milliseconds.

For Pandas DataFrames

If you’re working with pd.DataFrame instead of numpy arrays, just convert the DataFrame to a numpy array, run the vectorized operation, then convert back:

import pandas as pd

df = pd.DataFrame(arr)
indices_df = pd.DataFrame(indices)

# Convert to numpy, process, then convert back
result_np = df.values[:, :, np.newaxis].take(indices_df.values, axis=0).reshape(df.shape[0], -1)
result_df = pd.DataFrame(result_np)

This keeps the convenience of pandas while leveraging numpy’s speed.


内容的提问来源于stack exchange,提问作者DuFei

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 14:27:56