Python Numpy中的数组堆叠:UNIX和Windows之间的不同行为

Python Numpy中的数组堆叠:UNIX和Windows之间的不同行为,python,arrays,windows,unix,numpy,Python,Arrays,Windows,Unix,Numpy,注意:这是Python2.7,不是Py3 这是对先前问题的更新尝试。您要求我提供完整的代码、内容说明和示例输出文件。我会尽我最大的努力把它格式化好 该代码用于从荧光“平板阅读器”获取输入文件,并将读数转换为DNA浓度和质量。然后,它生成一个输出文件,该文件根据8x12板方案(DNA/分子工作标准)组织。行标记为“A,B,C,…,H”,列仅标记为1-12 根据用户输入,需要堆叠阵列以格式化输出。但是,当数组在UNIX中堆叠(打印或写入到输出文件)时,它们仅限于第一个字符 #Crea

注意:这是Python2.7,不是Py3

这是对先前问题的更新尝试。您要求我提供完整的代码、内容说明和示例输出文件。我会尽我最大的努力把它格式化好

该代码用于从荧光“平板阅读器”获取输入文件,并将读数转换为DNA浓度和质量。然后,它生成一个输出文件,该文件根据8x12板方案(DNA/分子工作标准)组织。行标记为“A,B,C,…,H”,列仅标记为1-12

根据用户输入,需要堆叠阵列以格式化输出。但是,当数组在UNIX中堆叠(打印或写入到输出文件)时,它们仅限于第一个字符

        #Create output
        Outfile = open('Total_DNA_{0}'.format(InfileName),"w")
        Outfile.write("DNA concentration (ng/uL):\n\n")
        Outfile.write("\t"+"\t".join([str(n) for n in col])+"\n")
        if orientation == "left": #Add filler to left, then add row to the left of filler
            ng_per_microliter = np.c_[filler,ng_per_microliter]
            ng_per_microliter = np.c_[row,ng_per_microliter]
            Outfile.write("\n".join(["\t".join([n for n in item]) for item in ng_per_microliter.tolist()])+"\n\n")
        elif orientation == "right": #Add rows to the left, and filler to the right
            ng_per_microliter = np.c_[row,ng_per_microliter]
            ng_per_microliter = np.c_[ng_per_microliter,filler]
            Outfile.write("\n".join(["\t".join([n for n in item]) for item in ng_per_microliter.tolist()])+"\n\n")
        Outfile.write("Total mass of DNA per sample (ng):\n\n")
        Outfile.write("\t"+"\t".join([str(n) for n in col])+"\n")
        if orientation == "left":
            ng_total = np.c_[filler,ng_total]
            ng_total = np.c_[row,ng_total]
            Outfile.write("\n".join(["\t".join([n for n in item]) for item in ng_total.tolist()]))
        elif orientation == "right":
            ng_total = np.c_[row,ng_total]
            ng_total = np.c_[ng_total,filler]
            Outfile.write("\n".join(["\t".join([n for n in item]) for item in ng_total.tolist()]))
        Outfile.close
换句话说,在Windows中,如果数组中的数字为247.5,它将打印完整的数字。但在UNIX环境(Linux/Ubuntu/MacOS)中,它会被截断为简单的“2”。在Windows中,-2.7的数字将正常打印,但在UNIX中仅打印为“-”

完整的代码可以在下面找到;请注意,最后一个区块是代码中最相关的部分:

上述代码执行必要的计算,以根据DNA“标准”的线性回归计算给定样本中的DNA浓度(ng/uL)和总质量(ng),该标准可以在第1列和第2列(用户输入=“左”)或第11列和第12列(用户输入=“右”)

上面的代码创建要与原始数组堆叠的数组。“filler”数组是根据用户输入的“right”或“left”来放置的(堆叠命令np.c_[]如下所示)

最后,我们将生成输出文件。这就是问题行为发生的地方

        #Create conditional statement, depending on where the standards are, to split the array
        if orientation == "right":
            #Next, we want to average the 11th and 12th values of each of the 8 rows in our numpy array 
            stds = fluor_array[:,[10,11]] #Creates a sub-array with the standard values (last two columns, (8x2))
            data = np.delete(fluor_array,(10,11),axis=1) #Creates a sub-array with the data (first 10 columns, (8x10))

        elif orientation == "left":
            #Next, we want to average the 1st and 2nd values of each of the 8 rows in our numpy array   
            stds = fluor_array[:,[0,1]] #Creates a sub-array with the standard values (first two columns, (8x2))
            data = np.delete(fluor_array,(0,1),axis=1) #Creates a sub-array with the data (last 10 columns, (8x10))

        else:
            print "Error: answer must be 'LEFT' or 'RIGHT'"

        std_av = np.mean(stds, axis=1) #creates an array of our averaged std values

        #Then, we want to subtract the average value from row 1 (the BLANK) from each of the 8 averages (above)
        std_av_st = std_av - std_av[0]

        #Run a linear regression on the points in std_av_st against known concentration values (these data = y axis, need x axis)
        x = np.array([0.00, 0.03, 0.10, 0.30, 1.00, 3.00, 10.00, 25.00])*10 #ng/uL*10 = ng/well
        xi = np.vstack([x, np.zeros(len(x))]).T #creates new array of (x, 0) values (for the regression only); also ensures a zero-intercept (when we use (x, 1) values, the y-intercept is not forced to be zero, and the slope is slightly inflated)
        m, c = np.linalg.lstsq(xi, std_av_st)[0] # m = slope for future calculations

        #Now we want to subtract the average value from row 1 of std_av (the average BLANK value) from all data points in "data"
        data_minus_blank = data - std_av[0]

        #Now we want to divide each number in our "data" array by the value "m" derived above (to get total ng/well for each sample; y/m = x)
        ng_per_well = data_minus_blank/m

        #Now we need to account for the volume of sample put in to the AccuClear reading to calculate ng/uL
        ng_per_microliter = ng_per_well/float(input_DNA_vol)

        #Next, we multiply those values by the volume of DNA sample (variable "ng")
        ng_total = ng_per_microliter*float(remainder_vol)

        #Set number of decimal places to 1
        ng_per_microliter = np.around(ng_per_microliter, decimals=1)
        ng_total = np.around(ng_total, decimals=1)
使用一个简单的print命令,我发现stacking命令numpy.c_[]是罪魁祸首(而不是数组写入命令)

因此,numpy.c_[]似乎不会在Windows中截断这些数字,但会在UNIX环境中将这些数字限制为第一个字符

在这两种平台上都可以使用哪些替代方案?如果不存在,我不介意创建一个特定于UNIX的脚本

谢谢你们的帮助和耐心。很抱歉,没有提前提供所有必要的信息

这些图像是屏幕截图,显示了Windows的正确输出以及我在UNIX中得到的结果(我试图为您格式化这些图像…但它们是一场噩梦)。我还包括了一个屏幕截图,显示了当我简单地打印数组“ng_/u微升”和“ng_总计”时在终端中获得的输出

使用一个简单的print命令,我发现stacking命令numpy.c_[]是罪魁祸首(而不是数组写入命令)

因此,numpy.c_[]似乎不会在Windows中截断这些数字,但会在UNIX环境中将这些数字限制为第一个字符

用简单的例子说明这些陈述
np.c_[]
不应该做任何不同的事情

在Py3中,默认字符串类型为unicode。和numpy 1.12

In [149]: col = [i for i in range(1,13)]
     ...: row = np.asarray(['A','B','C','D','E','F','G','H'])
     ...: filler = np.array(['-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-',]).reshape((8,2))
     ...: 
In [150]: col
Out[150]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
In [151]: "\t"+"\t".join([str(n) for n in col])+"\n"
Out[151]: '\t1\t2\t3\t4\t5\t6\t7\t8\t9\t10\t11\t12\n'
In [152]: filler
Out[152]: 
array([['-', '-'],
       ...
       ['-', '-'],
       ['-', '-']], 
      dtype='<U1')
In [153]: row
Out[153]: 
array(['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'], 
      dtype='<U1')
In [154]: row.shape
Out[154]: (8,)
In [155]: filler.shape
Out[155]: (8, 2)
In [159]: ng_per_microliter=np.arange(8.)+1.23
In [160]: np.c_[filler,ng_per_microliter]
Out[160]: 
array([['-', '-', '1.23'],
       ['-', '-', '2.23'],
       ['-', '-', '3.23'],
      ...
       ['-', '-', '8.23']], 
      dtype='<U32')
In [161]: np.c_[row,ng_per_microliter]
Out[161]: 
array([['A', '1.23'],
       ['B', '2.23'],
       ['C', '3.23'],
         ....
       ['H', '8.23']], 
      dtype='<U32')
并跟踪
dtype

对于V1.12发行说明(可能更早)

如果要转换到的字符串dtype在“安全”转换模式下不够长,无法保存正在转换的整数/浮点数组的最大值,那么astype方法现在将返回一个错误。以前,即使结果被截断,也允许强制转换

这可能在执行连接时起作用

使用一个简单的print命令,我发现stacking命令numpy.c_[]是罪魁祸首(而不是数组写入命令)

因此,numpy.c_[]似乎不会在Windows中截断这些数字,但会在UNIX环境中将这些数字限制为第一个字符

用简单的例子说明这些陈述
np.c_[]
不应该做任何不同的事情

在Py3中,默认字符串类型为unicode。和numpy 1.12

In [149]: col = [i for i in range(1,13)]
     ...: row = np.asarray(['A','B','C','D','E','F','G','H'])
     ...: filler = np.array(['-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-',]).reshape((8,2))
     ...: 
In [150]: col
Out[150]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
In [151]: "\t"+"\t".join([str(n) for n in col])+"\n"
Out[151]: '\t1\t2\t3\t4\t5\t6\t7\t8\t9\t10\t11\t12\n'
In [152]: filler
Out[152]: 
array([['-', '-'],
       ...
       ['-', '-'],
       ['-', '-']], 
      dtype='<U1')
In [153]: row
Out[153]: 
array(['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'], 
      dtype='<U1')
In [154]: row.shape
Out[154]: (8,)
In [155]: filler.shape
Out[155]: (8, 2)
In [159]: ng_per_microliter=np.arange(8.)+1.23
In [160]: np.c_[filler,ng_per_microliter]
Out[160]: 
array([['-', '-', '1.23'],
       ['-', '-', '2.23'],
       ['-', '-', '3.23'],
      ...
       ['-', '-', '8.23']], 
      dtype='<U32')
In [161]: np.c_[row,ng_per_microliter]
Out[161]: 
array([['A', '1.23'],
       ['B', '2.23'],
       ['C', '3.23'],
         ....
       ['H', '8.23']], 
      dtype='<U32')
并跟踪
dtype

对于V1.12发行说明(可能更早)

如果要转换到的字符串dtype在“安全”转换模式下不够长,无法保存正在转换的整数/浮点数组的最大值,那么astype方法现在将返回一个错误。以前,即使结果被截断,也允许强制转换


这可能在执行连接时起作用。

在用户hpaulj的帮助下,我发现这不是操作系统和环境之间行为不同的问题。这很可能是因为用户拥有不同版本的numpy

数组的串联自动将“float64”数据类型转换为“S1”(以匹配“filler”数组(“-”)和“row”数组('A'、'B'等))

较新版本的numpy(特别是V1.12.X)似乎允许在不进行这种自动转换的情况下连接数组


我仍然不确定在旧版本的numpy中如何解决这个问题,但建议人们升级他们的版本以获得全面性能应该是一件简单的事情。:)

在用户hpaulj的帮助下,我发现这不是操作系统和环境之间行为不同的问题。这很可能是因为用户拥有不同版本的numpy

数组的串联自动将“float64”数据类型转换为“S1”(以匹配“filler”数组(“-”)和“row”数组('A'、'B'等))

较新版本的numpy(特别是V1.12.X)似乎允许在不进行这种自动转换的情况下连接数组


我仍然不确定在旧版本的numpy中如何解决这个问题,但建议人们升级他们的版本以获得全面性能应该是一件简单的事情。:)

你走错方向了。让问题和例子更加紧凑,关注手头的问题,而不是更大、更难理解。这看起来像李
In [149]: col = [i for i in range(1,13)]
     ...: row = np.asarray(['A','B','C','D','E','F','G','H'])
     ...: filler = np.array(['-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-',]).reshape((8,2))
     ...: 
In [150]: col
Out[150]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
In [151]: "\t"+"\t".join([str(n) for n in col])+"\n"
Out[151]: '\t1\t2\t3\t4\t5\t6\t7\t8\t9\t10\t11\t12\n'
In [152]: filler
Out[152]: 
array([['-', '-'],
       ...
       ['-', '-'],
       ['-', '-']], 
      dtype='<U1')
In [153]: row
Out[153]: 
array(['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'], 
      dtype='<U1')
In [154]: row.shape
Out[154]: (8,)
In [155]: filler.shape
Out[155]: (8, 2)
In [159]: ng_per_microliter=np.arange(8.)+1.23
In [160]: np.c_[filler,ng_per_microliter]
Out[160]: 
array([['-', '-', '1.23'],
       ['-', '-', '2.23'],
       ['-', '-', '3.23'],
      ...
       ['-', '-', '8.23']], 
      dtype='<U32')
In [161]: np.c_[row,ng_per_microliter]
Out[161]: 
array([['A', '1.23'],
       ['B', '2.23'],
       ['C', '3.23'],
         ....
       ['H', '8.23']], 
      dtype='<U32')
print(repr(np.c_[row,ng_per_microliter]))