【问题标题】:How to use np.stack in this situation?在这种情况下如何使用 np.stack ?
【发布时间】:2017-05-16 03:33:27
【问题描述】:

我有两个 np.ndarray :

predictions = np.array([[0.2, 0.9], [0.01, 0.0], [0.3, 0.8], ...])
filenames = np.array(["file1", "file2", "file3", ...])

文件名中的每个文件对应预测中的每个数组:

file1==>[0.2, 0.9]

file2==>[0.01, 0.0]

file3==>[0.3,0.8] ...

我想将这两个数组中的值打印成一个csv文件,如下所示:

fileName        label1      label2
file1           0.2         0.9 
file2           0.1         0.0
file3           0.3         0.8

我希望用np.stack把这两个np.array合并成一个数据结构,然后用np.savetext(path, array, )输出到csv文件。

但是 np.stack(array, axis=1) 似乎只接受两个具有相同形状的数组。有没有办法让堆栈适用于这种情况?

【问题讨论】:

    标签: python numpy


    【解决方案1】:

    使用numpy.expand_dimsnumpy.hstask例程的解决方案:

    import numpy as np
    result = np.hstack((np.expand_dims(filenames, axis=1), predictions))
    
    # saving to csv file using `np.savetxt`:
    with open('./text_files/predictions.csv', 'wb') as fh:
        np.savetxt(fh, X= result, header='fileName\tlabel1\tlabel2', delimiter='\t', fmt='%-8s\t%-6s\t%-6s')
    

    predictions.csv(测试文件)内容:

    # fileName  label1  label2
    file1       0.2     0.9   
    file2       0.01    0.0   
    file3       0.3     0.8   
    

    【讨论】:

      【解决方案2】:

      您可以向文件名添加另一个维度,然后使用hstack() 将其与预测叠加:

      np.hstack([filenames[:, None], predictions])
      
      #array([['file1', '0.2', '0.9'],
      #       ['file2', '0.01', '0.0'],
      #       ['file3', '0.3', '0.8']], 
      #      dtype='|S32')
      

      【讨论】:

      • preds = np.hstack([filenames[:, None], predictions]) np.savetxt('my_submit.csv', preds, fmt='%d,%.5f, %.5f ',header='图像, ALB, BET', cmets='')
      • 为什么'np.savetxt'会产生这个错误:“TypeError: Mismatch between array dtype ('
      • dtype 将字符串数组连接到数字数组时是字符串。它只能格式化为%s。不是数字格式化程序。
      【解决方案3】:

      这是zip的一种方式:

      >>> np.array(zip(filenames, *zip(*predictions)))
      array([['file1', '0.2', '0.9'],
             ['file2', '0.01', '0.0'],
             ['file3', '0.3', '0.8']], 
            dtype='|S5')
      

      还有一个np.vstack

      >>> np.vstack((filenames, predictions.T)).T
      array([['file1', '0.2', '0.9'],
             ['file2', '0.01', '0.0'],
             ['file3', '0.3', '0.8']], 
            dtype='|S5')
      

      【讨论】:

        【解决方案4】:

        你有 2 个数组,一个是 2d 的数字,另一个是 1d 的字符串

        In [53]: predictions = np.array([[0.2, 0.9], [0.01, 0.0], [0.3, 0.8]])
            ...: filenames = np.array(["file1", "file2", "file3"])
        
        In [54]: predictions
        Out[54]: 
        array([[ 0.2 ,  0.9 ],
               [ 0.01,  0.  ],
               [ 0.3 ,  0.8 ]])
        In [55]: filenames
        Out[55]: 
        array(['file1', 'file2', 'file3'], 
              dtype='<U5')
        

        如果您向filenames 添加一个维度(因此它变为 (3,1)),您可以将其与另一个维度连接 - 请注意轴。我使用的是 Py3,所以我的默认字符串类型是 unicode (U5)。

        In [56]: arr = np.concatenate((filenames[:,None], predictions),axis=1)
        In [57]: arr
        Out[57]: 
        array([['file1', '0.2', '0.9'],
               ['file2', '0.01', '0.0'],
               ['file3', '0.3', '0.8']], 
              dtype='<U32')
        

        请注意,结果是字符串类型。这可能没问题。 column_stackvstack 也可以使用,但它们最终会像我一样调整尺寸并使用连接。

        np.stack 在新维度上连接数组。我认为您不需要 3d 数组。

        In [58]: np.savetxt('test', arr, fmt='%10s')
        In [59]: cat test
             file1        0.2        0.9
             file2       0.01        0.0
             file3        0.3        0.8
        

        您可以调整fmt,但使用字符串时您会遇到%s 的一些变化。 savetxt 也允许页眉和页脚。

        要对fmt 进行更多控制,例如小数位数等,我们必须构造一个结构化数组,将一个字符串字段与两个浮点字段混合在一起。如果需要,我可以对此进行扩展。

        另一种选择是仅zip 数组并写入行。 savetxt 在编写文本文件时不会做任何神奇的事情。

        In [65]: for f, n in zip(filenames, predictions):
            ...:     print('%s  %s'%(f, '%10.2f %10.2f'%tuple(n)))
            ...:     
        file1        0.20       0.90
        file2        0.01       0.00
        file3        0.30       0.80
        

        鉴于从 1 列字符串和 2 列浮点数组创建结构化数组的复杂性,最后一种 zip 方法可能是最简单的。

        结构化数组

        In [114]: arr = np.zeros((3,),np.dtype('U10,f,f'))
        In [115]: arr['f0']=filenames
        In [116]: arr['f1']=predictions[:,0]
        In [117]: arr['f2']=predictions[:,1]
        In [118]: np.savetxt('test',arr, fmt='%10s %10.2f %10.1f')
        In [119]: cat test
             file1       0.20        0.9
             file2       0.01        0.0
             file3       0.30        0.8
        

        构造这个数组的更简单的方法是:

        arr = np.rec.fromarrays((filenames, predictions[:,0], predictions[:,1]))
        

        我更喜欢制作这样的结构化数组:

        In [123]: dt=np.dtype([('files', 'U10'), ('pred', 'float64', (2,))])
        In [124]: dt
        Out[124]: dtype([('files', '<U10'), ('pred', '<f8', (2,))])
        In [125]: arr = np.zeros((3,),dtype=dt)
        In [126]: arr['files']=filenames
        In [127]: arr['pred']=predictions
        In [128]: arr
        Out[128]: 
        array([('file1', [0.2, 0.9]), ('file2', [0.01, 0.0]), ('file3', [0.3, 0.8])], 
              dtype=[('files', '<U10'), ('pred', '<f8', (2,))])
        

        但 np.savetxt 无法处理该复合数据类型。所以我不得不求助于将预测放在不同的字段中。

        pandas 在编写带有行标签的文件方面做得更好。

        【讨论】:

        • np.savetxt('test', arr, fmt='%10s'):这将概率放入一列,我想要 3 个不同的列。为什么这不起作用:“np.savetxt('test.csv', arr, fmt='%s,%.5f,%.5f', header='image, xx,yy')"?
        • 你的arrshape 是什么?我的是 (3,3)(见Out[57])。
        • 您的解决方案的问题是将所有值放在一列中。例如,我希望将每个“0.2 0.9”放入两个 csv 列中。
        • 我不明白。我的Out[59] 显示 3 列 - 标签和 2 个数字列。除了列标题之外,它与接受的答案相同。
        • 由于“fmt='%10s'”,您的第 59 行实际上在一列中,因为您只有一个格式变量。我认为它需要“%s, %s, %s”。顺便说一句,“%10s”中的“10”是什么?
        猜你喜欢
        • 2022-01-23
        • 2015-11-30
        • 2012-10-06
        • 2011-05-18
        • 2019-11-29
        • 2022-01-23
        • 2018-05-20
        • 2013-02-25
        • 1970-01-01
        相关资源
        最近更新 更多