【问题标题】:Python: Converting string to floats, reading floats into 2D array, if/then, reordering of rows?Python:将字符串转换为浮点数,将浮点数读入二维数组,如果/那么,重新排序行?
【发布时间】:2017-05-18 16:11:29
【问题描述】:

首先让我说我对 Python 一无所知,但我正在努力学习(似乎主要是通过挣扎)。我环顾了这个网站并试图拼凑代码来做我需要的事情,但我一直遇到问题。首先,我需要将一个包含 2 列和 512 行字符串的文件转换为浮点数,然后将它们放入 512x2 数组中。我检查第一列(所有行)是否有负值。如果为负,则添加 512。然后我需要按数字顺序重新排序行并写入/保存新数组。

关于我的第一个问题,转换为浮点数并将浮点数放入数组中。我有这段代码,是我根据别人的问题制作的:

with open("binfixtest.composite") as f: f_values = map(lambda l: l.strip().split(' '), f) print f_values newarray = [map(float, v) for v in f_values]

文件原格式:

-91. 0.444253325 -90. 0.883581936 -89. -0.0912338793

f_values 的新格式: ['-91. 0.444253325'], ['-90. 0.883581936'], ['-89. -0.0912338793']

我收到了错误:

Traceback (most recent call last): File "./binfix.py", line 10, in <module> newarray = [map(float, v) for v in f_values] ValueError: invalid literal for float(): -91. 0.444253325

我似乎无法修复。如果我不转换为浮点数,当我尝试将 512.0 添加到负行时,它会给我错误TypeError: cannot concatenate 'str' and 'float' objects

非常感谢任何帮助,因为我在这里完全一无所知。

【问题讨论】:

  • 您将拆分为 3 个空格,但空格数是可变的。用.split()就行了
  • 当您说“按数字顺序重新排列行”时请澄清。您是指第一项还是第二项?

标签: python arrays string


【解决方案1】:

如果您预计必须不时执行此类任务,我有一些建议。

让你的生活更轻松的事情是开始学习使用numpy 数组,而不是尝试使用你自己的数组(由列表组成)。

对于这个问题,你可以像这样使用numpy

>>> import numpy as np
>>> data = np.loadtxt('binfixtest.composite')
>>> data
array([[-91.    ,   0.44425332],
   [-90.        ,   0.88358194],
   [-89.        ,  -0.09123388]])

就是这样。完毕。您的数据现在位于一个充满浮点数的 numpy 数组中。

这是因为默认情况下,numpy.loadtxt method 将换行符读取为行分隔符,将空格(包括空格和制表符)读取为列分隔符,将数字读取为浮点数。如果您需要,还有很多其他选项可用于自定义 numpy 如何读取您的文件。

查看您的 numpy 数组

要访问第 0 行,请执行以下操作:

>>> data[0]
array([-91.        ,   0.44425332])

要访问地址 0,0 的值,请执行以下操作:

>>> data[0,0]
-91.0

要访问第 0 列,请执行以下操作(第一个冒号表示“所有行”):

>>> data[:,0]
array([-91., -90., -89.])

要访问行/列范围,请执行以下操作:

>>> data[1:, :2]
array([[-90.        ,   0.88358194],
       [-89.        ,  -0.09123388]])

上面的意思是“所有的行都从位置 1 开始,所有的列直到并且不包括位置 2”。您还可以执行1:3 之类的操作,这将得到从位置 1 开始的总共两行或两列 (3-1=2)。

更改您的 numpy 数组

要仅更改单个值,请执行以下操作:

>>> data[0,0] = 1
>>> data[0,0]
1.0

请注意,我们在0,0 更改的值已存储为浮点数,即使您分配给了一个 int。这是因为numpy 数组具有 ONE 数据类型,您放入该数组的任何内容都会尝试转换为该数据类型:

>>> data.dtype
dtype('float64')

如果你想将 512 添加到数组中特定地址的值,你可以这样做:

>>> data[0,0] = data[0,0] + 512
>>> data[0,0]
421.0

如果你想将 512 添加到整个第一列,你可以这样做:

>>> data[:,0] = data[:,0] + 512
>>> data
array([[  4.21000000e+02,   4.44253325e-01],
       [  4.22000000e+02,   8.83581936e-01],
       [  4.23000000e+02,  -9.12338793e-02]])

numpy 数组的有用操作

如果你想对一个数组(或一个数组的一部分)进行比较,这样做(它将返回一个新数组):

>>> data<0
array([[ True, False],
       [ True, False],
       [ True,  True]], dtype=bool)

仅获取数组中小于零的值的一种方法如下(还有其他方法):

>>> data*(data<0)
array([[-91.        ,   0.        ],
       [-90.        ,   0.        ],
       [-89.        ,  -0.09123388]])

之所以有效,是因为在numpyTrue 中,值的作用类似于 1,而 False 的值类似于 0

最后,如果您只想在值为负的情况下将 512 添加到整个第一列,您可以将所有这些放在一起并执行以下操作:

>>> data[:,0] = (data[:,0]+512)*(data[:,0]<0)
>>> data
array([[  4.21000000e+02,   4.44253325e-01],
       [  4.22000000e+02,   8.83581936e-01],
       [  4.23000000e+02,  -9.12338793e-02]])

将数组保存到新文件

如果您希望将数组保存到新文件,可以使用numpy.savetxt method

>>> np.savetxt('output.txt', data, fmt = '%.8f', delimiter = '    ', newline = '\n')

fmt = '%.8f' 参数指定应如何打印浮点值(在这种情况下,它将打印 8 位小数)。更多信息请咨询this part of the docs

【讨论】:

    【解决方案2】:

    第一部分:

    @njzk2 完全正确。只需删除文字空格以将 l.strip().split(' ') 更改为 l.strip().split() 即可纠正错误,您将看到 f_values 的以下输出:

    [['-91.', '0.444253325'], ['-90.', '0.883581936'], ['-89.', '-0.0912338793']]]

    newarray 的输出显示浮点值而不是字符串:

    [[-91.0, 0.444253325], [-90.0, 0.883581936], [-89.0, -0.0912338793]]

    第二部分:

    对于问题的第二部分“如果是否定的,添加 512”,一个简单的循环将是清晰和简单的,我非常相信清晰易读的代码。

    例如以下简单明了:

    for items in newarray: if items[0] < 0: items[0] += 512.00

    当我们在循环之后print newarray 时,我们看到以下内容:

    [[421.0, 0.444253325], [422.0, 0.883581936], [423.0, -0.0912338793]]

    【讨论】:

    • 啊!我不敢相信这是一个如此简单的修复。太令人沮丧了。感谢您的帮助。
    • 如果您不介意,我现在正在尝试处理 if/then 语句,该语句将 512 添加到第一列中的任何否定元素。我有:if newarray[:][0] &lt; 0: newarray[:][0] += 512.00 它似乎并没有改变任何东西。
    猜你喜欢
    • 1970-01-01
    • 2016-07-09
    • 1970-01-01
    • 2011-11-25
    • 2023-04-03
    • 2014-09-25
    • 2015-10-20
    • 1970-01-01
    • 2021-10-24
    相关资源
    最近更新 更多