【问题标题】:Inputting data from text as array从文本输入数据作为数组
【发布时间】:2015-01-20 21:51:04
【问题描述】:

大家好,

我有一个文本文件,其中包含以下格式的数据:

[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,1,4,9,0,0,0,0,2,8,13,47,0,0,0,0,0,0,12,139,11,1,0,0,4,8,44,139,14,4,1,1,30,45,80,139,34,28,0,0,7,34,117,43,0,0,0,0,0,5,40,139,78,9,0,0,0,12,100,139,121,42,4,1,6,7,16,122,101,117,22,13,4,1,10,0,0,0,0,0,0,10,9,33,7,0,0,0,0,42,87,139,20,2,0,0,0,6,95,83,9,5,8,39,73,13,45]

也就是说,每一行都是一个 128 维的样本,同样,我的文本文件中有 50k 个样本。

我正在对上述给定格式的数据执行 K-Means 聚类。当我直接输入数据时,它在以下代码中运行良好:

from sklearn.cluster import MiniBatchKMeans
import numpy

data = [[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,1,4,9,0,0,0,0,2,8,13,47,0,0,0,0,0,0,12,139,11,1,0,0,4,8,44,139,14,4,1,1,30,45,80,139,34,28,0,0,7,34,117,43,0,0,0,0,0,5,40,139,78,9,0,0,0,12,100,139,121,42,4,1,6,7,16,122,101,117,22,13,4,1,10,0,0,0,0,0,0,10,9,33,7,0,0,0,0,42,87,139,20,2,0,0,0,6,95,83,9,5,8,39,73,13,45]]   



mbkm = MiniBatchKMeans(init='k-means++', n_clusters=8, batch_size=100, n_init=10, max_no_improvement=10, verbose=0)
mbkm.fit(data)
mbk_means_cluster_centers = mbkm.cluster_centers_

numpy.set_printoptions(threshold=numpy.nan)
print mbk_means_cluster_centers

但是当我使用这段代码时

f = open("sample_input.txt", "r")
out = f.readlines()
for line in out:
    print line

要将文本文件中的内容读取为数组格式,它失败了,我收到错误“值错误:无法将字符串转换为浮点数”。

我无法理解我哪里出错了。请建议我一种更好的方法来运行代码。提前致谢!

PS:我在 ubuntu 平台上使用 python 2.7 进行编码。

【问题讨论】:

  • 这条线看起来很像 Python,你可能只需执行 "eval(line)" 并获得一个不错的整数数组。
  • 您可以通过将每一行解码为 json 字符串来获得所需的内容,因为该格式应与 json 列表类型一致。类似import json; line_list = json.loads(line);

标签: python arrays text


【解决方案1】:

我必须先说在文本文件中存储数据作为数组的代码表示是一个坏主意。如果可以,请将数据存储为可序列化的格式,例如 CSV 或 JSON。

发生的情况是您正在读取该行,它是字符串格式,而不是数组格式。当您遍历字符串时(字符串仍然是可枚举的),它会获取每个字母,但是您的代码会抱怨无法使用该字符串,因为它需要一个浮点数。

如果您真的需要以该格式读取该文件并且您信任该文件的来源,请尝试这样做。

f = open("sample_input.txt", "r") 
out = [eval(arr) for arr in f.readlines()]

请注意,这也会在该文件中执行代码,因此请确保您信任该文件的来源。

我的 python 经验有限,所以可能有更安全的方法。下次,使用 CSV 格式的数据文件。

【讨论】:

  • 该命令适用于有限的输入行。对于 50k 行输入,我收到“使用序列设置数组元素”错误。难道我做错了什么?我什至尝试了 Chris 指定的代码,甚至这向我显示了一个不同的错误。请帮忙。不知道如何运行该文件。我有另一个 30 万行的数据:/
【解决方案2】:

重申 Moox 的观点,使用 csv 存储此信息可能是个好主意。然后您可以使用csv 模块来解析文件。

避免 eval 也是一个好主意。您可以这样做以解析当前格式的数据 -

def line_to_list_of_ints(line):
    # Split each line on commas and convert to an int
    return [int(item) for item in line.split(',')]

with open("sample_input.txt", "r") as f:
    lines = [line.strip() for line in f] # Remove new lines / whitespace
lines = [line[1:-1] for line in lines] # Remove square brackets from each end
lines = [line_to_list_of_ints(line) for line in lines] # Convert the line to a list of integers

如果您使用的是 csv 文件,则可以将其简化为这样的内容 -

import csv

with open("sample_input.csv", "r") as f:
    reader = csv.reader(f)
    lines = []
    for line in reader:
        lines.append([int(item) for item in line])

【讨论】:

  • 除非你想要一个列表,否则不要调用 realines,只需遍历文件对象
  • @PadraicCunningham 你是对的,我已经更新了我的答案。
  • 您也可以将其设为生成器对象并使用单个列表传递line_to_list_of_ints(line[1:-1])
  • 或者干脆lines = [line_to_list_of_ints(line.rstrip()[1:-1]) for line in f]
【解决方案3】:

使用ast.literal_eval:

如果文件中有一个数组:

from ast import  literal_eval

with open("sample_input.txt") as f:
   out = literal_eval(f.read())
   for line in out:
       print line

0
0
0
0
0
0
0
0
...............

对于多个数组:

with open("in.txt") as f:
   for line in f:
       print literal_eval(line)

【讨论】:

    【解决方案4】:

    假设你的数据在mydata.txt...

    % sed '1idata=[ 
    s/$/,/;$a]' < mydata.txt > mydata.py
    

    创建一个可以在程序中导入的 python 模块

    from mydata import data
    

    【讨论】:

      猜你喜欢
      • 2015-04-27
      • 2020-07-21
      • 2020-04-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-13
      • 1970-01-01
      • 2015-01-25
      相关资源
      最近更新 更多