【问题标题】:Import file in Python (numpy) as contiguous memory array在 Python (numpy) 中导入文件作为连续内存数组
【发布时间】:2018-06-07 09:30:46
【问题描述】:

我想从一个文本文件中导入数据,并将其作为一个连续的内存数组读入。这是数据,每个受访者都用回车符分隔:

['vrouw', 43, '2', 'onbeantwoord', '2', '2', 'onbeantwoord', '']

['vrouw', 34, '2', 'onbeantwoord', '2', '2', 'onbeantwoord', '']

['vrouw', 32, '2', 'onbeantwoord', '2', '2', 'onbeantwoord', '']

['vrouw', 32, '2', 'onbeantwoord', '2', '2', 'onbeantwoord', '']

['vrouw', 43, '3', 'sport', '2', '2', 'onbeantwoord', '']

['vrouw', 32, '2', 'onbeantwoord', '2', '2', 'onbeantwoord', '']

['vrouw', 43, '2', 'onbeantwoord', '3', '3', 'collega', 'nee']

我尝试使用以下代码从文本文件中导入数据:

vragenlijst_data= np.genfromtxt('antwoorden.txt', delimiter=',', dtype=None, names=('geslacht', 'leeftijd', 'stelling1', 'doorvraag1', 'stelling2', 'stelling3', 'doorvraag3', 'opmerking'))

但是,这种方式我不能以矢量化方式使用 np.mean(来自 numpy 库),因为我没有连续的内存数组。有谁知道一种读取数据的方法,以便我拥有一个连续的内存数组(最好使用 numpy)?

【问题讨论】:

  • 您不能使用np.mean,因为您有一个带有字符串的dtype=object 数组。或者您期望在str 上使用np.mean 会产生什么输出?
  • 您想在所有数字列上使用 np.mean 还是只在 leeftijd 上使用?
  • 我只想在 'leftijd' 列上使用 np.mean
  • 描述 genfrom 测试的结果。 shaoe,dtype 等。括号和引号使读取该文件变得混乱。还有你想要什么样的意思?
  • genfromtxt 的结果是:。我想在 numpy 中计算 'leftijd' 的平均值。代码 'mean = np.mean([int(i[1]) for i in vragenlijst_data])' 有效,但我想以矢量化方式使用 np.mean,以便我可以使用 np.mean(vragenlijst_data[ 1])

标签: python python-2.7 numpy


【解决方案1】:

复制并粘贴您的行:

In [362]: txt
Out[362]: "['vrouw', 43, '2', 'onbeantwoord', '2', '2', 'onbeantwoord', '']\n\n['vrouw', 34, '2', 'onbeantwoord', '2', '2', 'onbeantwoord', '']\n\n['vrouw', 32, '2', 'onbeantwoord', '2', '2', 'onbeantwoord', '']\n\n['vrouw', 32, '2', 'onbeantwoord', '2', '2', 'onbeantwoord', '']\n\n['vrouw', 43, '3', 'sport', '2', '2', 'onbeantwoord', '']\n\n['vrouw', 32, '2', 'onbeantwoord', '2', '2', 'onbeantwoord', '']\n\n['vrouw', 43, '2', 'onbeantwoord', '3', '3', 'collega', 'nee']"

In [364]: data = np.genfromtxt(txt.splitlines(), delimiter=',',dtype=None, encoding=None)
In [365]: data
Out[365]: 
array([("['vrouw'", 43, " '2'", " 'onbeantwoord'", " '2'", " '2'", " 'onbeantwoord'", " '']"),
       ("['vrouw'", 34, " '2'", " 'onbeantwoord'", " '2'", " '2'", " 'onbeantwoord'", " '']"),
       ("['vrouw'", 32, " '2'", " 'onbeantwoord'", " '2'", " '2'", " 'onbeantwoord'", " '']"),
       ("['vrouw'", 32, " '2'", " 'onbeantwoord'", " '2'", " '2'", " 'onbeantwoord'", " '']"),
       ("['vrouw'", 43, " '3'", " 'sport'", " '2'", " '2'", " 'onbeantwoord'", " '']"),
       ("['vrouw'", 32, " '2'", " 'onbeantwoord'", " '2'", " '2'", " 'onbeantwoord'", " '']"),
       ("['vrouw'", 43, " '2'", " 'onbeantwoord'", " '3'", " '3'", " 'collega'", " 'nee']")],
      dtype=[('f0', '<U8'), ('f1', '<i8'), ('f2', '<U4'), ('f3', '<U15'), ('f4', '<U4'), ('f5', '<U4'), ('f6', '<U15'), ('f7', '<U7')])

结果是一个混合了字符串和数字字段的一维结构化数组,必须按名称引用,而不是列号。

'f1' 是数字,因为它在原文中没有引号。因此可以查看该字段,并轻松取其平均值:

In [367]: data['f1']
Out[367]: array([43, 34, 32, 32, 43, 32, 43])
In [368]: np.mean(data['f1'])
Out[368]: 37.0

genfromtxt 不会删除括号,所以 'f0' 字符串仍然有它们。

额外的引号层也使得将其他字段转换为整数变得更加困难。

如果文件具有更清晰的 csv 值,则更易于阅读和使用:

In [372]: txt1 = """vrouw, 43, 2, onbeantwoord, 2, 2, onbeantwoord, ''
     ...: vrouw, 34, 2, onbeantwoord, 2, 2, onbeantwoord, '' """
     ...: 
In [373]: 
In [373]: data1 = np.genfromtxt(txt1.splitlines(), delimiter=',',dtype=None, enc
     ...: oding=None)
In [374]: data1
Out[374]: 
array([('vrouw', 43, 2, ' onbeantwoord', 2, 2, ' onbeantwoord', " ''"),
       ('vrouw', 34, 2, ' onbeantwoord', 2, 2, ' onbeantwoord', " ''")],
      dtype=[('f0', '<U5'), ('f1', '<i8'), ('f2', '<i8'), ('f3', '<U13'), ('f4', '<i8'), ('f5', '<i8'), ('f6', '<U13'), ('f7', '<U3')])
In [375]: data1['f0']
Out[375]: array(['vrouw', 'vrouw'], dtype='<U5')
In [376]: data1['f1']
Out[376]: array([43, 34])
In [377]: data1['f5']
Out[377]: array([2, 2])

【讨论】:

    【解决方案2】:

    您的数据格式不正确,看起来只是print 的输出。我认为您不会找到任何库函数来使您的数据可用(gentext 使用格式错误的数据构建一个数组)。所以这里是:

    import re
    
    with open('antwoorden.txt') as f:
        lines = f.readlines()
    
    vragenlijst = []
    for line in lines:
        line = re.sub("[',\[\]]", '', line.strip())
        line = [x for x in line.split()]
        if len(line)==7:
            line += ['']
        vragenlijst.append(tuple(line))
    

    vragenlijst 现在是一个 8 元组的 python 列表,其中每个成员都是一个字符串。元组对于 numpy 的结构化数组是必需的。所以现在你像这样构建你的 dtype:

    vragenlijst_dtype = np.dtype([('geslacht', 'U10'), ('leeftijd', 'i4'), 
            ('stelling1', 'U10'), ('doorvraag1', 'U10'), ('stelling2', 'U10'), 
            ('stelling3', 'U10'), ('doorvraag3', 'U10'), ('opmerking', 'U10')])
    

    其中“U10”表示 10 个字符长的 unicode,而 i4 表示 4 个字节长的整数。如果它们不适合您的真实数据,您可以更改类型。

    然后:

    vragenlijst = np.array(vragenlijst, dtype=vragenlijst_dtype)
    list_mean = np.mean(vragenlijst['leeftijd'])
    

    输出“37.0”

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-22
      • 2015-11-12
      • 2014-09-17
      • 2016-12-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多