【问题标题】:Numpy / Pandas slicing based on intervals基于间隔的 Numpy / Pandas 切片
【发布时间】:2021-04-27 18:44:33
【问题描述】:

试图找出一种方法来分割 pandas / numpy 矩阵的不连续和不等长的行,以便我可以将值设置为一个公共值。有没有人为此找到一个优雅的解决方案?

import numpy as np
import pandas as pd
x = pd.DataFrame(np.arange(12).reshape(3,4))
#x is the matrix we want to index into

"""
x before:
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
"""
y = pd.DataFrame([[0,3],[2,2],[1,2],[0,0]]) 
#y is a matrix where each row contains a start idx and end idx per column of x

"""
   0  1
0  0  3
1  2  3
2  1  3
3  0  1
"""

我正在寻找的是一种根据 y 的行有效地选择不同长度的 x 切片的方法

x[y] = 0 
"""
x afterwards:
array([[ 0,  1,  2,  0],
       [ 0,  5,  0,  7],
       [ 0,  0,  0, 11]])

【问题讨论】:

  • 您可能正在寻找masking
  • for 循环赋值回
  • 感谢@ti7,我认为掩码在这里直接不起作用,因为条件不一定是单个布尔值,而是来自间隔列表
  • for 循环是当前运行的方法,但速度很慢..

标签: python pandas numpy stride


【解决方案1】:

屏蔽仍然有用,因为即使无法完全避免循环,主数据帧x 也不需要参与循环,因此这应该会加快速度:

mask = np.zeros_like(x, dtype=bool)

for i in range(len(y)):
    mask[y.iloc[i, 0]:(y.iloc[i, 1] + 1), i] = True
    
x[mask] = 0
x
    0   1   2   3
0   0   1   2   0
1   0   5   0   7
2   0   0   0   11

作为进一步的改进,如果可能,请考虑将 y 定义为 NumPy 数组。

【讨论】:

    【解决方案2】:

    我为你的问题定制了this答案:

    y_t = y.values.transpose()
    y_t[1,:] = y_t[1,:] - 1 # or remove this line and change '>= r' below to '> r`
    
    r = np.arange(x.shape[0])
    
    mask = ((y_t[0,:,None] <= r) & (y_t[1,:,None] >= r)).transpose()
    
    res = x.where(~mask, 0)
    res
    #     0   1   2   3
    # 0   0   1   2   0
    # 1   0   5   0   7
    # 2   0   0   0   11
    

    【讨论】:

      猜你喜欢
      • 2018-06-15
      • 1970-01-01
      • 1970-01-01
      • 2015-07-19
      • 2021-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-19
      相关资源
      最近更新 更多