如何逆转np.flatten()和映射的过程?

时间:2018-10-03 20:14:10

标签: python numpy dictionary

我有一个具有这种格式的目标值numpy数组,可以说10个维度(24,10)

|-- app

     |-- [+] configs
     |
     |
     |-- core
       |-- [+] authentication
       |-- [+] guards
       |-- [+] http
       |-- [+] interceptors
       |-- [+] layout
       |-- [+] mocks
       |-- [+] services
       |-- [+] strategies
       |-- core.module.ts
       |-- router.animations.ts
       |-- template-core.module.ts
       |-- theme.module.ts
       |-- ensureModuleLoadedOnceGuard.ts
       |-- logger.service.ts    
     |
     |     
     |-- modules
       |-- client
           |-- [+] components
           |-- client-routing.module.ts
           |-- client.module.ts
       |--- [+] other modules

     |
     |-- shared
          |-- [+] components
          |-- [+] directives
          |-- [+] pipes
          |-- [+] models
          |-- [+] module
      |
      |-- app-routing.module.ts
      |-- app.module.ts
      |-- etc ...
      |
|-- assets
     |-- images
     |-- icons
     |-- css
          |-- styles.scss

所以我应用了这张地图

Target = [[ 2,  0,  2,  0,  0,  3,  0,  0,  1,  0,  0, -2,  4, -2,  0,  0,
    -3, -3, -5,  1,  0,  0,  0,  2],...]

目标值现在是(10,24,5):

checker_presence = {
5: np.array([1,1,1,1,1], dtype=int),
4: np.array([1,1,1,1,0], dtype=int),
3: np.array([1,1,1,0,0], dtype=int),
2: np.array([1,1,0,0,0], dtype=int),
1: np.array([1,0,0,0,0], dtype=int),
0: np.array([0,0,0,0,0], dtype=int),
-1: np.array([-1,0,0,0,0], dtype=int),
-2: np.array([-1,-1,0,0,0], dtype=int),
-3: np.array([-1,-1,-1,0,0], dtype=int),
-4: np.array([-1,-1,-1,-1,0], dtype=int),
-5: np.array([-1,-1,-1,-1,-1], dtype=int)}

labels_ = np.array([list(map(checker_presence.__getitem__, row)) for row in target])

此后,我将flatten函数应用为一个数组(10,120):

  [[ 1,  1,  0,  0,  0],
   [ 0,  0,  0,  0,  0],
   [ 1,  1,  0,  0,  0],
   [ 0,  0,  0,  0,  0],
   [ 0,  0,  0,  0,  0],
   [ 1,  1,  1,  0,  0],
   [ 0,  0,  0,  0,  0],
   [ 0,  0,  0,  0,  0],
   [ 1,  0,  0,  0,  0],
   [ 0,  0,  0,  0,  0],
   [ 0,  0,  0,  0,  0],
   [-1, -1,  0,  0,  0],
   [ 1,  1,  1,  1,  0],
   [-1, -1,  0,  0,  0],
   [ 0,  0,  0,  0,  0],
   [ 0,  0,  0,  0,  0],
   [-1, -1, -1,  0,  0],
   [-1, -1, -1,  0,  0],
   [-1, -1, -1, -1, -1],
   [ 1,  0,  0,  0,  0],
   [ 0,  0,  0,  0,  0],
   [ 0,  0,  0,  0,  0],
   [ 0,  0,  0,  0,  0],
   [ 1,  1,  0,  0,  0]],...]

我的问题是如何将这一过程恢复为我的目标值

labels = np.array([i.flatten() for i in labels_])
[ 1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0, -1, -1,  0,  0,  0,  1,  1,  1,  1,  0, -1, -1,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, -1, -1, -1,  0,  0,
   -1, -1, -1,  0,  0, -1, -1, -1, -1, -1,  1,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  0,  0,
    0],...]

在此示例中,我仅使用一行来更好地理解。问题是我需要对神经网络进行此转换,但是要分析预测,则需要逆向过程。

3 个答案:

答案 0 :(得分:3)

虽然flatten会折叠尺寸,但reshape可以进行任意尺寸转换。它以函数和方法形式存在。快速示例:

import numpy as np
a = np.empty((10, 24, 5))
b = a.reshape(10, 120)  # or b = np.reshape(a, (10, 120))
print(b.shape)  # shows (10, 120)
c = b.reshape(10, 24, 5)  # or c = np.reshape(b, (10, 24, 5))
print(c.shape)  # shows (10, 24, 5)

答案 1 :(得分:2)

您可以使用嵌套列表理解:

import numpy as np

labels = [ 1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0, -1, -1,  0,  0,  0,  1,  1,  1,  1,  0, -1, -1,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, -1, -1, -1,  0,  0,
   -1, -1, -1,  0,  0, -1, -1, -1, -1, -1,  1,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  0,  0,
    0]

checker_presence = {
5: np.array([1,1,1,1,1], dtype=int),
4: np.array([1,1,1,1,0], dtype=int),
3: np.array([1,1,1,0,0], dtype=int),
2: np.array([1,1,0,0,0], dtype=int),
1: np.array([1,0,0,0,0], dtype=int),
0: np.array([0,0,0,0,0], dtype=int),
-1: np.array([-1,0,0,0,0], dtype=int),
-2: np.array([-1,-1,0,0,0], dtype=int),
-3: np.array([-1,-1,-1,0,0], dtype=int),
-4: np.array([-1,-1,-1,-1,0], dtype=int),
-5: np.array([-1,-1,-1,-1,-1], dtype=int)}

chunked = [labels[i:i + 5] for i in range(0, len(labels), 5)]

target = [key for chunk in chunked for key, value in checker_presence.items() if list(value)==chunk]

收益:

[2, 0, 2, 0, 0, 3, 0, 0, 1, 0, 0, -2, 4, -2, 0, 0, -3, -3, -5, 1, 0, 0, 0, 2]

答案 2 :(得分:1)

这是一个使用高级索引进行查找的解决方案,它应该比任何基于字典的方法都快很多。我还使用此方法添加了更快版本的正向地图。顺便说一句。如果您知道您的网络仅产生合法模式,则可以重塑形状,然后对最后一个轴求和以恢复原始表示形式。

import numpy as np

checker_presence = {
5: np.array([1,1,1,1,1], dtype=int),
4: np.array([1,1,1,1,0], dtype=int),
3: np.array([1,1,1,0,0], dtype=int),
2: np.array([1,1,0,0,0], dtype=int),
1: np.array([1,0,0,0,0], dtype=int),
0: np.array([0,0,0,0,0], dtype=int),
-1: np.array([-1,0,0,0,0], dtype=int),
-2: np.array([-1,-1,0,0,0], dtype=int),
-3: np.array([-1,-1,-1,0,0], dtype=int),
-4: np.array([-1,-1,-1,-1,0], dtype=int),
-5: np.array([-1,-1,-1,-1,-1], dtype=int)}

forward_lookup = np.empty((11, 5), int)
for k, v in checker_presence.items():
    forward_lookup[k] = v

reverse_lookup = np.full((3, 3, 3, 3, 3), 999999)
for k, v in checker_presence.items():
    reverse_lookup[(*v,)] = k

def forward(data, flatten=True):
    mapped = forward_lookup[data]
    return mapped.ravel() if flatten else mapped

def reverse(mapped, shape=(-1,), assume_all_legal=False):
    if assume_all_legal:
        return mapped.reshape(*shape, 5).sum(-1)
    return reverse_lookup[(*np.moveaxis(mapped.reshape(*shape, 5), -1, 0),)]

# small example

A = np.random.randint(-5, 6, (1, 5))
B = forward(A)
C = reverse(B, A.shape)
D = reverse(B, A.shape, True)

print(A)
print(B)
print(C)
print(D)

# large example

A = np.random.randint(-5, 6, (200, 1000))
B = forward(A)
C = reverse(B, A.shape)
D = reverse(B, A.shape, True)

assert np.all(A==C) and np.all(A==D)