【问题标题】:extract data from textfile [duplicate]从文本文件中提取数据[重复]
【发布时间】:2014-07-11 04:39:17
【问题描述】:

我需要从文本文件 (.txt) 中提取(具体为:LotLongnametype)数据,并从提取的数据中创建凸包。据我所知,提取的数据应该是浮点格式,而不是字符串。

文本文件有点像这样(包含更多数据):

location_type, parent_station, stop_id, stop_code, stop_name, stop_desc, stop_lat, stop_lon, zone_id
0,,10000,10000,"Albany Hwy After Armadale Rd","",-32.14796,116.020217222222,4
0,,10001,10001,"Albany Hwy After Frys L","",-32.144985,116.018336666667,3
0,,10002,10002,"Albany Hwy After Clarence Rd","",-32.1420722222222,116.017182777778,3
0,,10003,10003,"Albany Hwy After Rogers L","",-32.1391138888889,116.017382222222,3
0,,10004,10004,"Albany Hwy After Galliers Av","",-32.1365533333333,116.017569444444,3
0,,10005,10005,"Albany Hwy Armadale Kelmscott Hospital","Armadale Kelmscott Hospital",-32.1348155555556,116.017707222222,3
0,,10006,10006,"Albany Hwy After Lilian Av","",-32.1304322222222,116.018038333333,3

但直到现在我(从早上开始就一直在尝试和错误)只能设法提取整个数据,而不是特定的数据。

 try:
    fp = open(filename)
    myList = []
    next(fp)
    for f in fp:
        myList.append(list(f.strip().split(",")))

    fp.close()

    return myList

需要帮助来解决这个问题。非常感谢。

【问题讨论】:

  • 使用csv 模块。您的数据看起来像是逗号分隔的。
  • 这很可能已经在其他地方介绍过,但我不认为建议的副本是一个很好的副本。关于使用 python 读取 CSV 文件的最佳实践,这当然不是一个好的规范问题,因为它主要处理模块的特定功能。

标签: python extract


【解决方案1】:

http://www.coderholic.com/parsing-csv-data-in-python/ 看看那个链接,它向您展示了如何在 python 中处理 CSV。

以上链接中的代码:

import csv
data = csv.reader(open('data.csv'))
# Read the column names from the first line of the file
fields = data.next()
for row in data:
        # Zip together the field names and values
    items = zip(fields, row)
    item = {}
        # Add the value to our dictionary
    for (name, value) in items:
        item[name] = value.strip()

将数据放入字典中,然后您可以通过名称获取所需的值,而不必记住数据在列表中的位置

它基本上看起来像这样(示例):

{"id": "0", "name": "name", "date": "2009-01-01"},
{"id": "1", "name": "another name", "date": "2009-02-01"}

在你的情况下:

{"location_type": 0, "parent_station": "", "stop_id": 10000, "stop_code": 10000, "stop_name": "Albany Hwy After Armadale Rd", "stop_desc": "", "stop_lat": -32.14796, "stop_lon": 116.020217222222, "zone_id": 4}

【讨论】:

  • 不鼓励仅链接的答案,因为它们不能为问题提供独立的解决方案。也许您可以在回答中提供一个示例?
  • 也许值得将它应用到这个问题上,而不是直接从网站上复制它?
  • 考虑到提供的文件中每列都有很多数据,我决定使用网站上的字典示例来提高其可读性,并假设大多数人都能理解字典的目的的概要。否则很难看完整本词典。但是,正如您提到的,我将添加它。
【解决方案2】:

您可以使用csv 模块中的csv.DictReader

import csv
import pprint
pp = pprint.PrettyPrinter()
with open('filename') as file:
    dialect = csv.Sniffer().sniff(file.read(1024)) # determine the file format
    file.seek(0)                                   # rewind back to start of file
    dialect.skipinitialspace = True                # skip whitespace after delimiter
    dict_reader = csv.DictReader(file, dialect=dialect)
    for row in dict_reader:
        pp.pprint(row)

这会将 .csv 文件的每一行打印为字典。我正在使用pprint.PrettyPrinter 以更简洁的方式打印出字典。

csv.DictReader 对象会根据您第一行的名称自动为您创建键。 dialectskipinitialspace 选项可确保这些名称的开头不包含任何空格。

上述代码第一次迭代的输出:

{'location_type': '0',
 'parent_station': '',
 'stop_code': '10000',
 'stop_desc': '',
 'stop_id': '10000',
 'stop_lat': '-32.14796',
 'stop_lon': '116.020217222222',
 'stop_name': 'Albany Hwy After Armadale Rd',
 'zone_id': '4'}

dictionary 包含 key: value 对,因此要获得特定值,您可以通过其键来引用它。例如,要获取给定rowstop_name,您可以使用name = row['stop_name']。如果您想打印文件每一行的坐标、名称和类型,可以将上面的 for 循环更改为如下内容:

for row in dict_reader:
    lat = row['stop_lat']
    lon = row['stop_lon']
    name = row['stop_name']
    type = row['location_type']
    print '({},{}): {}, {}'.format(lat, lon, name, type)

您可以查找str.formathere。这基本上是构建包含变量的字符串的更好方法。

输出:

(-32.14796,116.020217222222): Albany Hwy After Armadale Rd, 0
(-32.144985,116.018336666667): Albany Hwy After Frys L, 0
(-32.1420722222222,116.017182777778): Albany Hwy After Clarence Rd, 0
(-32.1391138888889,116.017382222222): Albany Hwy After Rogers L, 0
(-32.1365533333333,116.017569444444): Albany Hwy After Galliers Av, 0
(-32.1348155555556,116.017707222222): Albany Hwy Armadale Kelmscott Hospital, 0
(-32.1304322222222,116.018038333333): Albany Hwy After Lilian Av, 0

编辑

例如,如果您想以浮点数形式获取所有纬度和经度的列表,您可以这样做:

import csv
with open('filename') as file:
    dialect = csv.Sniffer().sniff(file.read(1024)) # determine the file format
    file.seek(0)                                   # rewind back to start of file
    dialect.skipinitialspace = True                # skip whitespace after delimiter
    dict_reader = csv.DictReader(file, dialect=dialect)
    lats = []
    lons = []
    for row in dict_reader:
        lats.append(float(row['stop_lat']))
        lons.append(float(row['stop_lon']))

【讨论】:

  • 谢谢,但我的数据是 .txt 格式的。这意味着我需要先转换为 .csv。之后我可以将数据用于凸包和 kd 树吗?
  • @user3664111 .csv.txt 只是文件扩展名,您不必在它们之间进行转换。我在您的数据上测试了此解决方案,并且无论扩展名如何,它都可以正常工作。我认为这是解决您的问题的最佳方法,因为它使用内置的 python 模块而不是重新发明轮子。顺便说一句,不要忘记为您认为有用的答案投票并接受您最喜欢的答案。
  • 谢谢@Tom Fenech。它现在可以工作了,但是我如何从 dict 中只提取坐标、名称和类型。不要忘记,我是编程和 python 的新手。
  • @user3664111 当然,这取决于你想如何使用它们。我已经编辑了我的问题,以展示如何将它们打印出来。如果你想做一些不同的事情,你必须更具体。
  • 感谢您的帮助。我可能问错了问题。实际上,我想做的是,从文件中提取数据并处理它(尚未打印)。坐标将使用凸包包裹,并使用 kd-ranges 搜索获得最大和最小之间的范围。当我尝试将坐标放入凸包时,会导致错误,因为 dict_reader 没有 getitem 对象?如何解决这个问题?
【解决方案3】:

我喜欢在不导入特定库的情况下这样做:

d = {}
with open("file.txt") as f:
    for line in f:
        (location_type, parent_station, stop_id, stop_code, stop_name, stop_desc, stop_lat, stop_lon, zone_id) = line.split(",")
        d[stop_id] = (location_type, parent_station, stop_code, stop_name, stop_desc, stop_lat, stop_lon, zone_id)
print d

这更像是pythonic!

【讨论】:

  • 谢谢,我试过了,但是有错误。需要解压的值太多。
  • 我用你的测试文件做了它并立即得到了结果。检查您的数据,可能某处有一行具有额外值。
  • 还是不行。已经检查过了,一切都一样。
  • 编写自己的高度不灵活的解决方案没有什么比 Python 更“像 Python 一样”了。像 csv 这样的模块是 python 核心的一部分是有充分理由的!
猜你喜欢
  • 1970-01-01
  • 2016-09-15
  • 2020-12-20
  • 1970-01-01
  • 1970-01-01
  • 2011-04-20
  • 1970-01-01
相关资源
最近更新 更多