首页 > 解决方案 > 矢量化字符串连接 numpy

问题描述

所以我需要一种快速的方法来连接数组的行,如果它们是字符串并过滤掉空值和无值。第一种方法是将数据作为 pandas 数据框,在其中我将使用结果列填充数组,然后使用 df.update 更新数组,我将使用 df.apply() 应用操作,但我们知道 df .apply() 在大型数据帧上运行时会变得非常慢。

下一个方法是只用 numpy 处理它,问题是我们需要过滤掉空字符串值和非字符串值,因为我们只想连接实际上是字符串的列。我们想加入一个分隔符。所以让我们来看看我想要实现的几个例子

一个普通的分隔符为' - '的是

| A   | B   | C   | D   |
|-----+-----+-----+-----|
| 'a' | 'b' | 'c' | 'd' |
| 'e' | 'f' | 'g' | 'h' |

变成

| A   | B   | C   | D   | Result          |
|-----+-----+-----+-----+-----------------|
| 'a' | 'b' | 'c' | 'd' | 'a - b - c - d' |
| 'e' | 'f' | 'g' | 'h' | 'e - f - g - h' |

另一个使用 None 和非字符串相同分隔符的示例

| A    | B   | C   | D    |
|------+-----+-----+------|
| None | 'b' | 1   | 'd'  |
| 'e'  | 'f' | 'g' | None |

变成

| A    | B   | C   | D    | Result      |
|------+-----+-----+------+-------------|
| None | 'b' | 1   | 'd'  | 'b - d'     |
| 'e'  | 'f' | 'g' | None | 'e - f - g' |

我已经创建了一些带有掩码的 numpy 正是这样做的,但似乎仍然很慢

nan_mask = np.where(np.logical_or(operate_v == '', operate_v == ' ', operate_v == None), True, False)
operate_v[nan_mask] == ''
de = np.full((operate_v.shape[0], operate_v.shape[1] - 1), delimiter).astype('object')
V = np.zeros((operate_v.shape[1] + de.shape[1] , operate_v.shape[0])).astype('object')
de[nan_mask[:, :-1]] = ''
de[nan_mask[:, -1]] = ''
V[0::2] = operate_v.T
V[1::2] = de.T
done = np.sum(V, axis = 0)
df[:, target_idx] = done

所以基本上我正在创建一个空/无值所在的掩码,然后创建一个分隔符数组并根据 nan_mask 更新它并交织两个数组,以便我们可以对其求和,然后更新原始数据帧。希望这种方法有意义。还有一个实现只使用普通的python列表,它的性能远远优于numpy的方法,我们来看看。

empty = {
  None: True,
  ' ': True,
  '': True,
}

result = list(
  map(delimiter.join, map(
    lambda values: filter(
      lambda v: not empty.get(v), values
    ), zip(*data))))

由于每一行都不依赖于最后一行,我们应该能够通过矢量化来加快速度,但我似乎无法管理。我希望我正在尝试做的事情是有道理的,对加速它有什么帮助吗?

标签: pythonpandasnumpyvectorization

解决方案


推荐阅读