【问题标题】:Python read file into numpy array of list?Python将文件读入numpy列表数组?
【发布时间】:2018-06-26 17:44:40
【问题描述】:

如何读取包含每行长度可能与 ascii 数字不同的文本的文件。

前

APORRADASD
ASDSDASD

作为

0 -> [065,080,079,082,082,065,068,065,083,068]
1 -> [065,083,068,083,068,065,083,068]

然后将其减去 65(因为只有大写字母存在)。 当我尝试使用 for 循环读取每一行然后减去时会使过程非常慢(因为文件大约 300+MB)

data = np.genfromtxt('data.txt', dtype=np.object_)
for x in range(0,data.shape[0]):
    data[x] = [c - 65 for c in data[x]]

【问题讨论】:

  • 请添加一些代码来演示您的尝试。
  • 网上有很多资料教你如何从文件中读取,以及如何将字符转换为ASCII码。你被困在哪里了?
  • numpy 不会帮你。 numpy csv 读者使用常规 Python readline 和 split。他们希望这些线条有一个共同的长度。并且对于大多数处理,对象 dtype 列表数组比等效的列表列表要慢。
  • 天啊,对不起,我以为我已经添加了代码,-5Downvotes!!!!问题是由于文件很大,需要很多时间,我的方法一定效率低下......所以建议
  • 以这种方式使用genfromtxt 并没有做任何特别的事情。您是否尝试过通过简单的方式获取字符串:data = open(file).readlines()?

标签: python numpy


【解决方案1】:

试试这个:

ascii_conv = []
foo = "APORRADASD"
bar = list(foo)
for n in bar:
    ascii_conv.append(ord(n))

【讨论】:

    【解决方案2】:

    我将您的样本复制了 1000 次,并测试了几个选项。

    'all in one loop' 是一起读取和解析行:

    In [159]: with open('stack48307975.txt','rb') as f:
         ...:     data=[np.array(list(l.strip()))-65 for l in f]
         ...:        
    In [160]: len(data)
    Out[160]: 4000
    In [161]: data[:3]
    Out[161]: 
    [array([ 0, 15, 14, 17, 17,  0,  3,  0, 18,  3]),
     array([ 0, 18,  3, 18,  3,  0, 18,  3]),
     array([ 0, 15, 14, 17, 17,  0,  3,  0, 18,  3])]
    

    这样可以节省 getfromtxt 开销。大致相当于

    全部读取,然后解析:

    In [162]: with open('stack48307975.txt','rb') as f:
         ...:     dataB = f.readlines()
         ...:    
    In [163]: len(dataB)
    Out[163]: 4000
    In [164]: [[c-65 for c in row.strip()] for row in dataB][:3]
    Out[164]: 
    [[0, 15, 14, 17, 17, 0, 3, 0, 18, 3],
     [0, 18, 3, 18, 3, 0, 18, 3],
     [0, 15, 14, 17, 17, 0, 3, 0, 18, 3]]
    

    在 Py3 中,我必须使用 rb 打开以获取字节串,然后我们可以使用 c-65 进行转换。如果我使用 r 模式加载,我会得到 unicode 字符串,并且必须使用 ord(c)。

    我可以 read 将整个文件转换为一个字符串,然后将其转换为数组:

    In [165]: with open('stack48307975.txt','rb') as f:
         ...:     dataAll=f.read()
         ...:         
    In [166]: len(dataAll)
    Out[166]: 40000
    In [167]: dataAll[:13]
    Out[167]: b'APORRADASD\nAS'
    In [168]: dataOne =np.fromiter(dataAll,dtype='uint8')
    In [169]: dataOne.shape
    Out[169]: (40000,)
    In [170]: dataOne[:13]
    Out[170]: array([65, 80, 79, 82, 82, 65, 68, 65, 83, 68, 10, 65, 83], dtype=uint8)
    

    但是把它分成几行需要一些摆弄

    In [171]: idx = np.where(dataOne==10)[0]
    In [172]: idx
    Out[172]: array([   10,    19,    30, ..., 39979, 39990, 39999], dtype=int32)
    
    In [175]: np.split(dataOne-65, idx)[:3]
    Out[175]: 
    [array([ 0, 15, 14, 17, 17,  0,  3,  0, 18,  3], dtype=uint8),
     array([201,   0,  18,   3,  18,   3,   0,  18,   3], dtype=uint8),
     array([201,   0,  15,  14,  17,  17,   0,   3,   0,  18,   3], dtype=uint8)]
    

    或者为了更好的处理\n:

    In [178]: idx0=[0]+(idx[:-1]+1).tolist()
    In [179]: [dataOne[i:j]-65 for i,j in zip(idx0, idx)][:4]
    Out[179]: 
    [array([ 0, 15, 14, 17, 17,  0,  3,  0, 18,  3], dtype=uint8),
     array([ 0, 18,  3, 18,  3,  0, 18,  3], dtype=uint8),
     array([ 0, 15, 14, 17, 17,  0,  3,  0, 18,  3], dtype=uint8),
     array([ 0, 18,  3, 18,  3,  0, 18,  3], dtype=uint8)]
    

    我已经做了一些计时,但如果你自己做会更有意义。

    【讨论】:

      猜你喜欢
      • 2015-02-24
      • 2018-09-29
      • 2019-08-24
      • 2018-03-25
      • 2017-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多