如何在不使用循环的情况下获得大于或小于NumPy数组中每个项目的索引?



我正在从头开始编写决策树算法,现在我正试图将数据分成组,其中每个组包含的值大于或等于或小于包含连续DataFrame列值的NumPy数组中的每个值,并获得这些分割目标的平均值。我的代码到目前为止:

for i in range(len(columns)):
col = columns[i]
# cont - list of continous columns in my DataFrame
if col in cont:
values  = xs[col].values
targets = y.values
for j in range(len(values)):
value = values[j]
greater_idx = np.where(values >= value)[0]
less_idx    = np.where(values <  value)[0]
targets_greater = targets[greater_idx].sum()
targets_less    = targets[less_idx]   .sum()
print(targets_greater/(j+1))
print(targets_less   /(j+1))

xs DataFrame的长度几乎是400k,所以循环非常慢,它每次都会杀死我的Jupyter Notebook内核。我知道应该有一种方法可以完全摆脱这个循环,但我不确定如何做到这一点。

与其用矢量化的方式来执行比较,不如让算法有很大的改进空间:

  1. np.argsort(sorted_idxs)得到xs[col].values的排序索引。
  2. 使用np.insert(np.cumsum(targets[sorted_idxs]), 0, 0)[:-1]可以为xs[col].values中的每个值获得target_less的向量。
  3. target_less[0](0)是xs[col].values中最低的元素的target_less值-到"unsort"target_less可以使用unsort_idx = np.argsort(sorted_idxs)target_less[unsort_idx]

现在你有所有的target_less值为所有的值在数组中(target_greater当然很容易通过targets.sum() - target_less获得)。

编辑:

下面是与建议一致的代码:

import numpy as np
import pandas as pd
xs = pd.DataFrame(np.random.random(10000))
y = pd.Series(np.random.randint(0, 2, size=10000))
sorted_idxs = np.argsort(xs[0].values)
sorted_values = xs[0].values[sorted_idxs]
sorted_targets = y.values[sorted_idxs]
sorted_targets_less = np.insert(np.cumsum(sorted_targets), 0, 0)[:-1]
unsorted_idxs = np.argsort(sorted_idxs)
targets_less = sorted_targets_less[unsorted_idxs]
for i, target_less_value in enumerate(targets_less):
assert target_less_value == y.values[np.where(xs.values < xs.values[i])[0]].sum()

一个警告:上面假设在x .values中有一组严格不同的值。如果有重复的值,则需要调整进行累积和的部分。

相关内容

  • 没有找到相关文章

最新更新