【问题标题】:Resizing a numpy array without padding在不填充的情况下调整 numpy 数组的大小
【发布时间】:2023-03-16 05:38:01
【问题描述】:

我有一组数据,我正在使用numpy.loadtxt 读取 3 个特定列,行数是灵活的。我想将数据写入具有新形状的新文件,即 9 列,但我只想用原始数据顺序填充这个新形状,因此原始行 0、1 和 2 将进入新行 0。 .. 原来的第 3、4 和 5 行到新的第 1 行等等。

对于我的测试文件,使用x.reshape(-1, 9) 成功了,但我碰巧有正确数量的数据点来填充新数组。如果我尝试使用行数不能被 9 整除的原始数据,则会出现以下错误...

ValueError: cannot reshape array of size 34149 into shape (9)

我的解决方案是使用 np.reshape(x, (1, -1) 然后计算行数并使用 np.resize(x, (num_rows, 9)) 但它从一开始就用数据填充最后一行 - 我需要一个解决方案,在最后一行没有数据

谢谢

【问题讨论】:

  • “nothing”的一个问题是它不能用处理其他数据的相同fmt 格式化(假设它是数字)。另外,您如何建议使用(可能)不规则行加载这个新的 csv?

标签: python arrays numpy resize reshape


【解决方案1】:

考虑这个虚拟数据:

>> x = np.random.randint(0,10,(4,3))
>> x

array([[0, 3, 9],
       [1, 9, 7],
       [2, 9, 6],
       [7, 4, 3]])

如果我理解正确,您想在.reshape((-1,9)) 它之前用两行np.nan 填充它。为什么在这个例子中多出了 2 行?因为这是添加到x 长度的较小数字,所以它成为3 的倍数(从而使条目总数可以被9 整除)。

一般来说,您希望将 (3-len(x)%3)%3 行添加到 x (不要被计算吓到,随意用更易读的东西替换它,以确保最终的条目数是可整除的9)。

总而言之,如果我理解正确,您的问题的单行解决方案是:

>> np.r_[x, np.full(((3-len(x)%3)%3,3),np.nan)].reshape((-1,9))

array([[ 0.,  3.,  9.,  1.,  9.,  7.,  2.,  9.,  6.],
       [ 7.,  4.,  3., nan, nan, nan, nan, nan, nan]])

更多解释:

  • np.full((something,3), np.nan) 生成一个带有 np.nan 值的 ndarray full(当然,可以随意将 np.nan 替换为您认为“nothing”的任何值);
  • 然后使用numpy.r_ 将其附加到您的原始数组x
  • 最终将reshaped 根据您的请求发送至(-1,9)

【讨论】:

  • 这很好用,除了我现在得到nan 写在我有重复数据之前的地方。我认为这是因为我正在读取 str 中的数据并将其写入 str。我这样做的原因是,这是我可以让它完全按照小数位读取的数据写入数据的唯一方法(即,我希望将 0 写为 0,将 3 个小数位写成 3小数位,2 dp 写成 2 dp 等)。我应该指出我是新手,所以我知道这可能不是最好的解决方案!
  • 我仍然不确定您想要实现什么。顺便说一句,这就是为什么总是建议在您的原始问题中包含一些示例代码、示例输入以及示例“预期结果”。那么你想要的结果是什么do? numpy 数组中那些额外的单元格将如何填充? (例如,我的示例中的最后 6 个单元格中当前包含 np.nan
  • 我刚刚阅读了您编辑的回复,所以也许我将问题与小数位问题混淆了。我用"" 替换了np.nan,这在一定程度上有效,但是我仍然有一些我什么都不想要的空间......这可能是也可能不是新文件的问题,我还不确定!
  • @sbeercan,如果我错了,请纠正我,但我相信你正在同时处理几个主题:(1)如何快速填充数组并重塑它(我相信是这个问题的主要话题)。 (2)格式化numpy数组的输出。 (3) 在同一个数组中保存多个数据类型?... => 请再次考虑我的示例中的最后 6 个单元格,其中当前包含 np.nan - 您希望计算机的内存在这些单元格中保存什么细胞?
  • 基本上我有传统形式的数据,3列(它是x,y,z数据),我想转换成一个新的形式,保存为一个文件,以便在成像中读取软件。但新形式很奇怪....它基本上是每行上的 9 个数据点逐行填充(即 x0, y0, z0, x1, y1, z1, x2, y2, z2 其中数字是索引原始行),当它到达末尾时,我不希望任何形式的额外数据填充最后一个空格,我只希望它以最终数据点停止
【解决方案2】:

使用 flat 迭代器填充数组的一种简单而快速的方法:

In [180]: arr = np.arange(1,13).reshape(3,4)
In [181]: arr
Out[181]: 
array([[ 1,  2,  3,  4],
       [ 5,  6,  7,  8],
       [ 9, 10, 11, 12]])
In [182]: res = np.zeros((3,5),int)
In [183]: res.flat[:arr.size] = arr
In [184]: res
Out[184]: 
array([[ 1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10],
       [11, 12,  0,  0,  0]])

显然,“填充”取决于我们最初放入 res 的内容。对于数值数据,0 和 1 是最简单的。其他值也是可能的,例如 nan 用于浮点数,或 '' 用于字符串条目。

In [191]: res = np.zeros((3,5),'U10')
In [192]: res
Out[192]: 
array([['', '', '', '', ''],
       ['', '', '', '', ''],
       ['', '', '', '', '']], dtype='<U10')
In [193]: res.flat[:arr.size] = arr
In [194]: res
Out[194]: 
array([['1', '2', '3', '4', '5'],
       ['6', '7', '8', '9', '10'],
       ['11', '12', '', '', '']], dtype='<U10')

但是您希望如何将此数组写入文件? savetxt 期望使用大小和数据类型一致的行。 %s fmt 可以写任何东西,但你会失去大多数格式和对齐控制。

这最后一个看起来不像 csv 太糟糕:

In [195]: np.savetxt('test', res, delimiter=',', fmt='%10s')
In [196]: cat test
         1,         2,         3,         4,         5
         6,         7,         8,         9,        10
        11,        12,          ,          ,          

它甚至可以加载:

In [199]: np.loadtxt('test', dtype='str', delimiter=',')
Out[199]: 
array([['         1', '         2', '         3', '         4',
        '         5'],
       ['         6', '         7', '         8', '         9',
        '        10'],
       ['        11', '        12', '          ', '          ',
        '          ']], dtype='<U10')

In [201]: np.genfromtxt('test', dtype=float, delimiter=',')
Out[201]: 
array([[ 1.,  2.,  3.,  4.,  5.],
       [ 6.,  7.,  8.,  9., 10.],
       [11., 12., nan, nan, nan]])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-05-10
    • 1970-01-01
    • 2015-07-05
    • 2020-07-15
    • 1970-01-01
    • 2016-09-29
    • 1970-01-01
    • 2016-12-18
    相关资源
    最近更新 更多