使用numpy将列拆分为两列

时间:2014-02-19 05:12:03

标签: python numpy

我有一个包含11列的文本文件,我用np.genfromtxt打开了它。

第三栏如下

   The Column
+220.18094-0.28421
+58.24577+0.08044
+58.24498+0.08177
+58.24552+0.08175
+86.55739-0.04768
+179.60575-0.34409
+86.55622-0.04726
+86.55649-0.04723
+86.55548-0.04718
+86.55879-0.04705
+86.55696-0.04685
+43.95906+0.14121
+356.95494+0.21770
+356.95594+0.21763 

我想将仅此列保存到新文本文件将列拆分为两列,如下所示

Txt文件:

+220.18094 -0.28421
+58.24577  +0.08044
+58.24498  +0.08177
+58.24552  +0.08175
+86.55739  -0.04768
+179.60575 -0.34409
+86.55622  -0.04726
+86.55649  -0.04723
+86.55548  -0.04718
+86.55879  -0.04705
+86.55696  -0.04685
+43.95906  +0.14121
+356.95494 +0.21770
+356.95594 +0.21763 

我该怎么做?

4 个答案:

答案 0 :(得分:1)

假设您已将这两列数据作为字符串列表读取,请使用re将字符串拆分为数字:

In [479]: d
Out[479]: 
['+220.18094-0.28421',
 '+58.24577+0.08044',
 '+58.24498+0.08177',
 '+58.24552+0.08175',
 '+86.55739-0.04768',
 '+179.60575-0.34409',
 '+86.55622-0.04726',
 '+86.55649-0.04723',
 '+86.55548-0.04718',
 '+86.55879-0.04705',
 '+86.55696-0.04685',
 '+43.95906+0.14121',
 '+356.95494+0.21770',
 '+356.95594+0.21763']

In [480]: import re
     ...: [map(float, re.findall('[-+][^-+]*', i)) for i in d]
Out[480]: 
[[220.18094, -0.28421],
 [58.24577, 0.08044],
 [58.24498, 0.08177],
 [58.24552, 0.08175],
 [86.55739, -0.04768],
 [179.60575, -0.34409],
 [86.55622, -0.04726],
 [86.55649, -0.04723],
 [86.55548, -0.04718],
 [86.55879, -0.04705],
 [86.55696, -0.04685],
 [43.95906, 0.14121],
 [356.95494, 0.2177],
 [356.95594, 0.21763]]

编辑:

当我将列定义为d = data [:,2] d给出数组([nan,nan,nan,...,nan,nan,nan]),为什么? < / p>

您的文件可能包含数字和字符串的混合,使用np.genfromtxt(fname, dtype=object)并打印它以检查您是否成功阅读。

答案 1 :(得分:1)

def edit_file():
    f = open('file.txt', 'r')
    lines = f.readlines()
    f.close()

    f1 = open('file.txt', 'w')
    for line in lines:
        line = line.replace('+','  +')
        line = line.replace('-','  -')
        f1.write(line)
    f1.close()

file.txt的:

  +220.18094  -0.28421
  +58.24577  +0.08044
  +58.24498  +0.08177
  +58.24552  +0.08175
  +86.55739  -0.04768
  +179.60575  -0.34409
  +86.55622  -0.04726
  +86.55649  -0.04723
  +86.55548  -0.04718
  +86.55879  -0.04705
  +86.55696  -0.04685
  +43.95906  +0.14121
  +356.95494  +0.21770
  +356.95594  +0.21763

如果您愿意,可以使用“replace()”以简单的方式完成。

答案 2 :(得分:0)

仅读入第三列:

d = np.genfromtxt('yourfile.txt',usecols=(2),dtype=None)

要拆分并转换为浮点数,您可以这样做:

g = np.array([re.split(' ',y.replace('-',' -')) for y in [x.replace('+',' ') for x in d]],dtype=float)

并保存到档案:

np.savetxt('yournewfile.txt',g)

答案 3 :(得分:0)

2021 年的答案

自从最初提出这个问题以来的七年里,情况发生了变化,之前的答案似乎并没有真正回答这个问题的定义。我最近遇到了这个问题,并在发现这个未完全回答的问题后发现了一个解决方案。如果其他人在尝试做同样的事情时偶然发现了这个问题,我希望这个解决方案能让他们重新开始行动。

问题

原始问题说明有 11 列使用 numpy 的 genfromtxt 函数加载。第三列应该被拆分并以固定的列格式保存到一个单独的文件中。

该问题的正确答案将显示如何获取该特定列,将其拆分,然后以正确的格式将其写入单独的文件。我们使用的方法适用于 numpy 数组中的任何列,因此该解决方案可以很容易地应用于其他问题。

解决方案

这个解决方案就是我做到的。如果有更有效的方法,请在下方评论。

1.导入库

我们正在使用 numpy,所以我们需要导入它。

import numpy as np

我们还将使用 re 拆分列中的字符串,因此也将其导入。

import re

2.读取数据

首先,我们将根据需要使用 genfromtxt 进行阅读。问题没有说明使用了哪些参数,因此我们将依赖许多默认值。

d = np.genfromtxt('data.csv', dtype=str, delimiter=',', skip_header=1, encoding='UTF-8')

在这一行中,我们正在加载一个 data.csv,它具有以逗号分隔的字符串值、一个标题行以及以 UTF-8 编码的所有内容。您会注意到 dtype 显式设置为 str这很重要。如果使用None,数组的结构会有所不同,下面的代码会失败,因此请确保使用dtype=str

3.拆分第三列

这是棘手的部分。我们需要取出要拆分的单个列,在其上运行 map 函数以拆分列中的字符串,然后将它们重新组合在一起。

c1 = np.hstack([*map(lambda x: re.findall(r'[-+]\d+\.\d+',x), d[:, 2])]).reshape(d.shape[0], 2)

要解压的东西太多了,所以让我们仔细看看。 lambda x: re.findall('[-+]\d+',x) 函数将输入字符串拆分为两个单独的字符串并保留其符号。它在 map(..., d[:,2]) 中使用,该函数将函数映射到第三列的每一行(列索引 2,因为它是从零开始的)。如果您直接将 np.hstack 函数放入 map 的最近更改将引发警告,因此我们需要将其转换为列表,然后将其用作 np.hstack 函数中的参数称呼。一种方法是[*map(...)],这就是我们所做的。这解释了 np.hstack 函数,但我们还没有完成。它将返回一维数组而不是二维数组。我们需要根据有多少列来 reshape 它。在这种情况下,这个数字不是 11,因为我们只从一列拆分为两列进行工作。

4.加入列(可选)

问题不要求重新组装列,但我需要这样做。我想其他人也会这样做,所以我就是这样做的。使用 np.hstack 很容易,如下所示:

d = np.hstack((d[:,0:2], c1, d[:,3:]))

注意我们是如何传递一个包含三个数组的列表的。第一个代表通向第三列的列,然后我们得到了第三列变成的两列,最后我们得到了第三列之后的列。双括号不是错字。 np.hstack 函数接受一个参数,因此我们创建了一个列表来用作该参数,而不是传递三个参数。如果拆分第一列或最后一列,则列表中将只有两个项目。

5.写入文件

哇! 说了很多,但我们还没有完成。现在我们需要将拆分列以指定格式写入数据文件。该格式似乎是第一列左对齐的 10 个字符的字符串和右列的 8 个字符的字符串,用空格分隔。为此,我们将使用 np.savetxt

np.savetxt('data.txt',c1,fmt='%-10s %8s')

最后的笔记

如果您已经做到了这一点,那么您已经从许多列中分离出一列,并可能将它们重新组合以创建一个比您开始时多出一列的表格,或者您有一个包含空格分隔值的文件。伟大的!不过有一个警告。在此练习期间,我们已强制所有内容都为字符串。如果要将值处理为浮点数或其他任何值,则必须转换 numpy 数组。

就目前而言,我相信这个答案完全回答了最初的问题,并希望证明对其他试图拆分 2d numpy 数组列的人有用。

以下是所有内容:

import numpy as np
import re
d = np.genfromtxt('data.csv', dtype=str, delimiter=',', skip_header=1, encoding='UTF-8')
c1 = np.hstack([*map(lambda x: re.findall(r'[-+]\d+\.\d+',x), d[:, 2])]).reshape(d.shape[0], 2)
d = np.hstack((d[:,0:2], c1, d[:,3:]))
np.savetxt('data.txt',c1,fmt='%-10s %8s')

干杯!