是否有更密集的方法来有条件地分离数据?
Is there a more dense method to conditionally separate data?
我想知道是否有更密集的方法来执行以下操作,这实际上是按行拆分列分隔的数据,并根据行的最终条目分为三个类别之一:
xi_test_0 = [xi_test_sc[i] for i in range(len(xi_test_sc)) if y_test[i] == 0]
xii_test_0 = [xii_test_sc[i] for i in range(len(xii_test_sc)) if y_test[i] == 0]
y_test_0 = [y_test[i] for i in range(len(y_test)) if y_test[i] == 0]
xi_test_1 = [xi_test_sc[i] for i in range(len(xi_test_sc)) if y_test[i] == 1]
xii_test_1 = [xii_test_sc[i] for i in range(len(xii_test_sc)) if y_test[i] == 1]
y_test_1 = [y_test[i] for i in range(len(y_test)) if y_test[i] == 1]
xi_test_2 = [xi_test_sc[i] for i in range(len(xi_test_sc)) if y_test[i] == 2]
xii_test_2 = [xii_test_sc[i] for i in range(len(xii_test_sc)) if y_test[i] == 2]
y_test_2 = [y_test[i] for i in range(len(y_test)) if y_test[i] == 2]```
为每个要中断的条件创建一组布尔数组:
split_index = {i: y_test == i for i in range(3)}
根据此布尔索引将您的数据分组。
xi_test_split = {i: xi_test_sc[idx, :] for i, idx in split_index.items()}
xii_test_split = {i: xii_test_sc[idx, :] for i, idx in split_index.items()}
y_test_split = {i: y_test[idx, :] for i, idx in split_index.items()}
xi_test_0
、xi_test_1
等都由一个仅在数字常量上有所不同的表达式进行初始化——所以首先要将它们转换成列表:
xi_test = [
[xi_test_sc[i] for i in range(len(xi_test_sc)) if y_test[i] == j]
for j in range(3)
]
xii_test = [
[xii_test_sc[i] for i in range(len(xii_test_sc)) if y_test[i] == j]
for j in range(3)
]
y_test_n = [
[y_test[i] for i in range(len(y_test)) if y_test[i] == j]
for j in range(3)
]
我们还可以通过 zip
ping 我们正在迭代的两个列表而不是使用 range
:
来简化单个列表理解
xi_test = [
[a for a, b in zip(xi_test_sc, y_test) if b == j]
for j in range(3)
]
xii_test = [
[a for a, b in zip(xii_test_sc, y_test) if b == j]
for j in range(3)
]
y_test_n = [
[a for a, b in zip(y_test, y_test) if b == j]
for j in range(3)
]
现在我们要看的代码变少了,很容易看出它们也有一个值不同——所以让我们把整个东西变成一个字典:
test_data = {
name: [[a for a, b in zip(sc_data, y_test) if b == j] for j in range(3)]
for name, sc_data in (
('xi', xi_test_sc), ('xii', xii_test_sc), ('y', y_test)
)
}
这与您的原始代码生成的数据相同,没有进行所有复制和粘贴操作。 xi_test_0
现在是 test_data['xi'][0]
,y_test_1
现在是 test_data['y'][1]
,等等。
或者,如果您更喜欢将每个列表分配给不同的命名变量,而不是在字典中创建名称键:
xi, xii, y = (
[[a for a, b in zip(sc_data, y_test) if b == j] for j in range(3)]
for sc_data in (xi_test_sc, xii_test_sc, y_test)
)
如果这些都是 numpy 数组,你可以使用掩码:
xi_test_0 = xi_test_sc[y_test==0]
y_test_0 = y_test[y_test==0]
xi_test_1 = xi_test_sc[y_test== 1]
xii_test_1 = xii_test_sc[y_test == 1]
... and so on ...
或者,如果您希望结果是 0、1、2 中性数对应于您的 _0、_1、_2 变量名称后缀的二维矩阵:
mask = y_test == np.arange(3)[:,None]
xi_test_n = xi_test_sc[mask]
xii_test_n = xii_test_sc[mask]
...
我想知道是否有更密集的方法来执行以下操作,这实际上是按行拆分列分隔的数据,并根据行的最终条目分为三个类别之一:
xi_test_0 = [xi_test_sc[i] for i in range(len(xi_test_sc)) if y_test[i] == 0]
xii_test_0 = [xii_test_sc[i] for i in range(len(xii_test_sc)) if y_test[i] == 0]
y_test_0 = [y_test[i] for i in range(len(y_test)) if y_test[i] == 0]
xi_test_1 = [xi_test_sc[i] for i in range(len(xi_test_sc)) if y_test[i] == 1]
xii_test_1 = [xii_test_sc[i] for i in range(len(xii_test_sc)) if y_test[i] == 1]
y_test_1 = [y_test[i] for i in range(len(y_test)) if y_test[i] == 1]
xi_test_2 = [xi_test_sc[i] for i in range(len(xi_test_sc)) if y_test[i] == 2]
xii_test_2 = [xii_test_sc[i] for i in range(len(xii_test_sc)) if y_test[i] == 2]
y_test_2 = [y_test[i] for i in range(len(y_test)) if y_test[i] == 2]```
为每个要中断的条件创建一组布尔数组:
split_index = {i: y_test == i for i in range(3)}
根据此布尔索引将您的数据分组。
xi_test_split = {i: xi_test_sc[idx, :] for i, idx in split_index.items()}
xii_test_split = {i: xii_test_sc[idx, :] for i, idx in split_index.items()}
y_test_split = {i: y_test[idx, :] for i, idx in split_index.items()}
xi_test_0
、xi_test_1
等都由一个仅在数字常量上有所不同的表达式进行初始化——所以首先要将它们转换成列表:
xi_test = [
[xi_test_sc[i] for i in range(len(xi_test_sc)) if y_test[i] == j]
for j in range(3)
]
xii_test = [
[xii_test_sc[i] for i in range(len(xii_test_sc)) if y_test[i] == j]
for j in range(3)
]
y_test_n = [
[y_test[i] for i in range(len(y_test)) if y_test[i] == j]
for j in range(3)
]
我们还可以通过 zip
ping 我们正在迭代的两个列表而不是使用 range
:
xi_test = [
[a for a, b in zip(xi_test_sc, y_test) if b == j]
for j in range(3)
]
xii_test = [
[a for a, b in zip(xii_test_sc, y_test) if b == j]
for j in range(3)
]
y_test_n = [
[a for a, b in zip(y_test, y_test) if b == j]
for j in range(3)
]
现在我们要看的代码变少了,很容易看出它们也有一个值不同——所以让我们把整个东西变成一个字典:
test_data = {
name: [[a for a, b in zip(sc_data, y_test) if b == j] for j in range(3)]
for name, sc_data in (
('xi', xi_test_sc), ('xii', xii_test_sc), ('y', y_test)
)
}
这与您的原始代码生成的数据相同,没有进行所有复制和粘贴操作。 xi_test_0
现在是 test_data['xi'][0]
,y_test_1
现在是 test_data['y'][1]
,等等。
或者,如果您更喜欢将每个列表分配给不同的命名变量,而不是在字典中创建名称键:
xi, xii, y = (
[[a for a, b in zip(sc_data, y_test) if b == j] for j in range(3)]
for sc_data in (xi_test_sc, xii_test_sc, y_test)
)
如果这些都是 numpy 数组,你可以使用掩码:
xi_test_0 = xi_test_sc[y_test==0]
y_test_0 = y_test[y_test==0]
xi_test_1 = xi_test_sc[y_test== 1]
xii_test_1 = xii_test_sc[y_test == 1]
... and so on ...
或者,如果您希望结果是 0、1、2 中性数对应于您的 _0、_1、_2 变量名称后缀的二维矩阵:
mask = y_test == np.arange(3)[:,None]
xi_test_n = xi_test_sc[mask]
xii_test_n = xii_test_sc[mask]
...