Python numpy ndarray从文本

时间:2016-04-28 20:06:53

标签: python numpy multidimensional-array

基于this answer,我使用changethis方法

import numpy as np
import os

def changethis(pos):
    appex = sfile[pos[1]-1][:pos[2]] + '*' + file[pos[1]-1][pos[2]+len(pos[0]):]
    file[pos[1]-1] = appex

pos = ('stack', 3, 16)
sfile = np.genfromtxt('in.cpp',dtype='str',delimiter=os.linesep)
changethis(pos)
print(file)

其中in.cpp是包含以下内容的源文件:

/* Multi-line 
comment
*/

#include <iostream>
#include <fstream>

using namespace std;

int main (int argc, char *argv[]) {
  int linecount = 0;
  double array[1000], sum=0, median=0, add=0;
  string filename;
  if (argc <= 1)
      {
          cout << "Error" << endl;
          return 0;
      }

我得到了输出:

['using namespace std;' 'int main (int argc, char *argv[]) {'
 'int linecount = *' 'double array[1000], sum=0, median=0, add=0;'
 'string filename;' 'if (argc <= 1)' '{' 'cout << "Error" << endl;'
 'return 0;' '}']

请注意{{1}中缺少多行注释包含语句空行的行}}

我不明白为什么会发生这种情况,因为ndarray设置为每个行内更改字符。

有关输出如何的任何建议:

delimiter

3 个答案:

答案 0 :(得分:2)

再次抱歉使用genfromtxt,没有理解您的意图,只是试图为问题提供可能的解决方案。作为该特定解决方案的后续(已提供其他解决方案),您可以这样做:

import numpy as np
import os

def changethis(pos):
    # Notice file is in global scope
    appex = file[pos[1]-1][:pos[2]] + '*' + file[pos[1]-1][pos[2]+len(pos[0]):]
    file[pos[1]-1] = appex

pos = ('stack', 3, 16)
file = np.array([i for i in open('in.txt','r')]) # instead of genfromtext.
changethis(pos)
print(file)

,结果是:

['/* Multi-line \n' 'comment\n' '*/\n*' '\n' '#include <iostream>\n'
 '#include <fstream>\n' '\n' 'using namespace std;\n' '\n'
 'int main (int argc, char *argv[]) {\n' '  int linecount = 0;\n'
 '  double array[1000], sum=0, median=0, add=0;\n' '  string filename;\n'
 '  if (argc <= 1)\n' '      {\n' '          cout << "Error" << endl;\n'
 '          return 0;\n' '      }']

编辑:另一个用户提到的另一个相关点是我用于文件的范围。我不是故意告诉你在全球范围内做的事情,我想解释一下这个功能是否正常,因为文件在全球范围内。在任何情况下,您都可以创建一个函数来保存范围:

import numpy as np
import os

def changeallthese(poslist,path):
    def changethis(pos):
        appex = file[pos[1]-1][:pos[2]-1] + '*' + file[pos[1]-1][pos[2]-1+len(pos[0]):]
        file[pos[1]-1] = appex
    file = np.array([str(i) for i in open(path,'r')])
    for i in poslist:
        changethis(i)
    return file

poslist = [('stack', 3, 16),('stack', 18, 1),('/* Multi-line', 1, 1)]
file =   changeallthese(poslist,'in.txt')
print(file)

,结果是:

['* \n' 'comment\n' '*/\n*' '\n' '#include <iostream>\n'
 '#include <fstream>\n' '\n' 'using namespace std;\n' '\n'
 'int main (int argc, char *argv[]) {\n' '  int linecount = 0;\n'
 '  double array[1000], sum=0, median=0, add=0;\n' '  string filename;\n'
 '  if (argc <= 1)\n' '      {\n' '          cout << "Error" << endl;\n'
 '          return 0;\n' '* }']

要将数组写入文件,您可以使用Python中的普通文件写入系统:

fid = open('out.txt','w')
fid.writelines(file)
fid.close()

,或者使用numpy中的一个函数(但我不确定它是否会添加更多的轮廓,所以要小心):

np.savetxt('out.txt',file,fmt='%s')

答案 1 :(得分:1)

如果文件不是太大:

import numpy as np
import os

def changethis(linelist,pos):
    appex = linelist[pos[2]-1][:pos[3]] + pos[1] + linelist[pos[2]-1][pos[3]+len(pos[0]):]
    linelist[pos[2]-1] = appex

pos = ('Multi','Three', 1, 3)

with open('in.cpp','r')  as f:
    lines=f.readlines()
    changethis(lines,pos)
print(''.join(lines))

readlines将你的文件变成一个行列表(这是一个内存效率低而且速度很慢,但可以完成工作。如果不到1k行就应该没问题。)

pos外,该函数还将行列表作为输入。我还修改了函数,使用pos[0]代替pos[1],而不是*pos[2]和字符pos[3]之后。{/ p>

我得到这个作为输出:

/* Three-line 
comment
*/

#include <iostream>
#include <fstream>

using namespace std;

int main (int argc, char *argv[]) {
  int linecount = 0;
  double array[1000], sum=0, median=0, add=0;
  string filename;
  if (argc <= 1)
      {
          cout << "Error" << endl;
          return 0;
      }

答案 2 :(得分:1)

如果您想要一个表示文件行的字符串列表,请打开该文件并使用readlines()

with open('in.cpp') as f:
    lines = f.readlines()

# Have changethis take the list of lines as an argument
changethis(lines, pos)

不要使用np.genfromtxt;这是一个表格数据解析器,具有您不想要的各种行为,例如将#视为行注释标记。

根据您打算对此列表执行的操作,您甚至可以避免需要明确的行列表。此外,file是变量名称的错误选择(它隐藏了内置的file),而changethis应该将列表作为参数而不是全局变量。一般来说,你得到的早期答案非常糟糕。