从 ND 到 1D 阵列

2025-02-27 09:06:00
admin
原创
74
摘要:问题描述:假设我有一个数组a:a = np.array([[1,2,3], [4,5,6]]) array([[1, 2, 3], [4, 5, 6]]) 我想将其转换为一维数组(即列向量):b = np.reshape(a, (1,np.product(a.shape))) 但这又回来了ar...

问题描述:

假设我有一个数组a

a = np.array([[1,2,3], [4,5,6]])

array([[1, 2, 3],
       [4, 5, 6]])

我想将其转换为一维数组(即列向量):

b = np.reshape(a, (1,np.product(a.shape)))

但这又回来了

array([[1, 2, 3, 4, 5, 6]])

这与以下内容不同:

array([1, 2, 3, 4, 5, 6])

我可以取该数组的第一个元素,手动将其转换为一维数组:

b = np.reshape(a, (1,np.product(a.shape)))[0]

但这要求我知道原始数组有多少维(并且在处理更高维度时连接 [0])

是否存在一种与维度无关的方法可以从任意 ndarray 中获取列/行向量?


解决方案 1:

使用np.ravel(用于 1D 视图)或np.ndarray.flatten(用于 1D 副本)或np.ndarray.flat(用于 1D 迭代器):

In [12]: a = np.array([[1,2,3], [4,5,6]])

In [13]: b = a.ravel()

In [14]: b
Out[14]: array([1, 2, 3, 4, 5, 6])

请注意,如果可能,将ravel()返回。因此,修改也会修改。如果 1D 元素在内存中连续,则返回,但如果例如使用非单位步长(例如)对另一个数组进行切片,则将返回 。view`abaravel()viewcopya`a = x[::2]

如果您想要的是副本而不是视图,请使用

In [15]: c = a.flatten()

如果您只想要一个迭代器,请使用np.ndarray.flat

In [20]: d = a.flat

In [21]: d
Out[21]: <numpy.flatiter object at 0x8ec2068>

In [22]: list(d)
Out[22]: [1, 2, 3, 4, 5, 6]

解决方案 2:

In [14]: b = np.reshape(a, (np.product(a.shape),))

In [15]: b
Out[15]: array([1, 2, 3, 4, 5, 6])

或者,简单地说:

In [16]: a.flatten()
Out[16]: array([1, 2, 3, 4, 5, 6])

解决方案 3:

我想看看包括unutbu在内的答案中提到的函数的基准测试结果。

还要指出的是,numpy doc建议在 case view 的情况下使用arr.reshape(-1)。(即使ravel在以下结果中速度稍快一些)


TL;DRnp.ravel性能最强(但差距很小)。

基准

功能:

  • np.ravel:如果可能的话,返回视图

  • np.reshape(-1):如果可能的话,返回视图

  • np.flatten:返回副本

  • np.flat:返回numpy.flatiter。类似于iterable

numpy 版本:'1.18.0'

ndarray不同尺寸的执行时间

+-------------+----------+-----------+-----------+-------------+
|  function   |   10x10  |  100x100  | 1000x1000 | 10000x10000 |
+-------------+----------+-----------+-----------+-------------+
| ravel       | 0.002073 |  0.002123 |  0.002153 |    0.002077 |
| reshape(-1) | 0.002612 |  0.002635 |  0.002674 |    0.002701 |
| flatten     | 0.000810 |  0.007467 |  0.587538 |  107.321913 |
| flat        | 0.000337 |  0.000255 |  0.000227 |    0.000216 |
+-------------+----------+-----------+-----------+-------------+

结论

ravel并且reshape(-1)的执行时间是一致的,并且与 ndarray 大小无关。但是,ravel速度稍快,但reshape在重塑大小方面提供了灵活性。(也许这就是为什么numpy doc建议使用它的原因。或者在某些情况下reshape返回 view 而不ravel返回)。

如果您正在处理大尺寸的 ndarray,使用flatten可能会导致性能问题。建议不要使用它。除非您需要数据的副本来做其他事情。

使用的代码

import timeit
setup = '''
import numpy as np
nd = np.random.randint(10, size=(10, 10))
'''

timeit.timeit('nd = np.reshape(nd, -1)', setup=setup, number=1000)
timeit.timeit('nd = np.ravel(nd)', setup=setup, number=1000)
timeit.timeit('nd = nd.flatten()', setup=setup, number=1000)
timeit.timeit('nd.flat', setup=setup, number=1000)

解决方案 4:

对于具有不同大小的数组列表,请使用以下命令:

import numpy as np

# ND array list with different size
a = [[1],[2,3,4,5],[6,7,8]]

# stack them
b = np.hstack(a)

print(b)

输出:

[1 2 3 4 5 6 7 8]

解决方案 5:

最简单的方法之一是使用flatten(),如以下示例:

 import numpy as np

 batch_y =train_output.iloc[sample, :]
 batch_y = np.array(batch_y).flatten()

我的阵列是这样的:

    0
0   6
1   6
2   5
3   4
4   3
.
.
.

使用后flatten()

array([6, 6, 5, ..., 5, 3, 6])

这也是此类错误的解决方案:

Cannot feed value of shape (100, 1) for Tensor 'input/Y:0', which has shape '(?,)' 

解决方案 6:

虽然这没有使用 np 数组格式,(懒得修改我的代码)但这应该可以满足您的要求...如果您确实想要一个列向量,您将需要转置向量结果。这完全取决于您打算如何使用它。

def getVector(data_array,col):
    vector = []
    imax = len(data_array)
    for i in range(imax):
        vector.append(data_array[i][col])
    return ( vector )
a = ([1,2,3], [4,5,6])
b = getVector(a,1)
print(b)

Out>[2,5]

因此,如果您需要转置,您可以执行以下操作:

def transposeArray(data_array):
    # need to test if this is a 1D array 
    # can't do a len(data_array[0]) if it's 1D
    two_d = True
    if isinstance(data_array[0], list):
        dimx = len(data_array[0])
    else:
        dimx = 1
        two_d = False
    dimy = len(data_array)
    # init output transposed array
    data_array_t = [[0 for row in range(dimx)] for col in range(dimy)]
    # fill output transposed array
    for i in range(dimx):
        for j in range(dimy):
            if two_d:
                data_array_t[j][i] = data_array[i][j]
            else:
                data_array_t[j][i] = data_array[j]
    return data_array_t

解决方案 7:

所有建议的解决方案中最好且最快的是:np.reshape()

%timeit img1ary = np.reshape(img2ary,(np.product(img2ary.shape),1))
9.3 µs ± 69.8 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

%timeit img1ary = img2ary.ravel()
157 ns ± 1.32 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

%timeit img1ary = img2ary.flatten()
961 ns ± 5.77 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   3868  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   2711  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Freshdesk、ClickUp、nTask、Hubstaff、Plutio、Productive、Targa、Bonsai、Wrike。在当今快速变化的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多企业在项目管理过程中面临着诸多痛点,如任务分配不...
项目管理系统   44  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Monday、TeamGantt、Filestage、Chanty、Visor、Smartsheet、Productive、Quire、Planview。在当今快速变化的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多项目经理和团队在管理复杂项目时,常...
开源项目管理工具   42  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Smartsheet、GanttPRO、Backlog、Visor、ResourceGuru、Productive、Xebrio、Hive、Quire。在当今快节奏的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多企业在选择项目管理工具时常常面临困惑:...
项目管理系统   44  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用