【问题标题】:Corresponding float in two lists两个列表中对应的浮点数
【发布时间】:2015-04-21 19:51:31
【问题描述】:

我有两个 CSV 文件。
第一个,当被视为一个列表时,看起来像这样:

('Rubus idaeus', '10.0', '56.0')
('Neckera crispa', '9.8785', '56.803')
('Dicranum polysetum', '9.1919', '56.0456')
('Sphagnum subnitens', '9.1826', '56.6367')
('Taxus baccata', '9.61778', '55.68833')
('Sphagnum papillosum', '9.1879', '56.0442')

这些列是“物种”、“经度”和“纬度”。 它们是在现场进行的观察。
另一个文件也是 CSV 文件。模拟真实事物的测试。它看起来像这样:

{'y': '58.1', 'x': '22.1', 'temp': '14'}
{'y': '58.2', 'x': '22.2', 'temp': '10'}
{'y': '58.3', 'x': '22.3', 'temp': '1'}
{'y': '58.4', 'x': '22.4', 'temp': '12'}
{'y': '58.5', 'x': '22.5', 'temp': '1'}
{'y': '58.6', 'x': '22.6', 'temp': '6'}
{'y': '58.7', 'x': '22.7', 'temp': '0'}
{'y': '58.8', 'x': '22.8', 'temp': '13'}
{'y': '58.9', 'x': '22.9', 'temp': '7'}

这两个文件确实很长。

我有观察,现在我想在包含气候数据的文件中找到最接近的较低数字,然后将该行附加到另一行,因此输出变为:

('Dicranum polysetum', '9.1919', '56.0456', 'y': '9.1', 'x': '56.0', 'temp': '7')

我尝试通过使用DictReader 遍历 CSV 文件来创建嵌套循环,但它的嵌套速度非常快。并且需要大量的循环才能完成整个过程。
有人知道方法吗?

我目前的代码很差,但我尝试了几种循环方式,我认为我的整个方法存在根本性的问题。

import csv
fil = csv.DictReader(open("TestData.csv"), delimiter=';')
navn = "nyDK_OVER_50M.csv"
occu = csv.DictReader(open(navn), delimiter='\t')

for row in fil:
    print 'x=',row['x']
    for line in occu:
        print round(float(line['decimalLongitude']),1)
        if round(float(line['decimalLongitude']),1) == row['x']:
            print 'You did it, found one dam match'

这是我的两个文件的链接,所以你不必编造任何数据,以防你知道可以推动我前进的东西。

https://www.dropbox.com/s/lmstnkq8jl71vcc/nyDK_OVER_50M.csv?dl=0 https://www.dropbox.com/s/v22j61vi9b43j78/TestData.csv?dl=0

最好的问候, 马蒂亚斯

【问题讨论】:

  • 气候数据中的 x 和 y 是什么?纬度/经度?
  • 您是否考虑将数据存储在en.wikipedia.org/wiki/K-d_tree 中?这种找到最近邻居的方法是 O(log(n)) 时间。
  • 您是否有每 0.1 度的温度,或者您的温度网格是否缺少数据?在前一种情况下,问题是微不足道的。
  • 我的温度为 0.1。它不应该丢失任何数据。
  • x 和 y 是纬度/经度。

标签: python python-2.7 csv


【解决方案1】:

因为你说没有丢失的温度数据点,那么解决问题就容易多了:

import csv

# temperatures
fil = csv.DictReader(open("TestData.csv"), delimiter=';')
# species
navn = "nyDK_OVER_50M.csv"
occu = csv.DictReader(open(navn), delimiter='\t')

d = {}
for row in fil:
    x = '{:.1f}'.format(float(row['x']))
    y = '{:.1f}'.format(float(row['y']))
    try:
        d[x][y] = row['temp']
    except KeyError:
        d[x] = {y:row['temp']}

for line in occu:
    x = '{:.1f}'.format(round(float(line['decimalLongitude']),1))
    y = '{:.1f}'.format(round(float(line['decimalLatitude']),1))
    temp = d[x][y]
    line['temp'] = temp
    line['x'] = x
    line['y'] = y
    print(line)

【讨论】:

  • 谢谢,我会尽快仔细看看。现在它在第 21 行给我一个错误: temp = d[x][y] KeyError: '56.0'
  • 好的,那是因为你的温度网格并不像你说的那样完整。它缺少数据。而是查看 scikit 最近邻居:scikit-learn.org/stable/modules/neighbors.html
  • 难道不能将 56 和 56.0 视为两个不同的东西吗?网格是完整的,它必须是:)
  • 不,因为我以相同的方式格式化了字符串;即用一位小数四舍五入。也许您没有上传正确的数据?
【解决方案2】:

这是一个解决方案,它使用numpy 计算每个数据项到x,y 点的欧几里得距离,并将该项目与距离最小的x,y 数据元组中的数据连接起来。

import numpy
import operator

# read the data into numpy arrays
testdata = numpy.genfromtxt('TestData.csv', delimiter=';', names=True)
nyDK     = numpy.genfromtxt('nyDK_OVER_50M.csv', names=True, delimiter='\t',\
                            dtype=[('species','|S64'),\
                                   ('decimalLongitude','float32'),\
                                   ('decimalLatitude','float32')])

# extract the x,y tuples into a numpy array or [(lat,lon), ...]
xy        = numpy.array(map(operator.itemgetter('x', 'y'), testdata))
# this is a function which returns a function which computes the distance
# from an arbitrary point to an origin
distance  = lambda origin: lambda point: numpy.linalg.norm(point-origin)

# methods to extract the (lat, lon) from a nyDK entry
latlon    = operator.itemgetter('decimalLatitude', 'decimalLongitude')
getlatlon = lambda item: numpy.array(latlon(item))

# this will transfrom a single element of the nyDK array into
# a union of it with its closest climate data
def transform(item):
    # compute distance from each x,y point to this item's location
    # and find the position of the minimum
    idx = numpy.argmin( map(distance(getlatlon(item)), xy) )
    # return the union of the item and the closest climate data
    return tuple(list(item)+list(testdata[idx]))

# transform all the entries in the input data set
result = map(transform, nyDK)

print result[0:3]

输出:

[('Rubus idaeus', 10.0, 56.0, 15.0, 51.0, 14.0),
 ('Neckera crispa', 9.8785, 56.803001, 15.300000000000001, 51.299999999999997, 2.0),
 ('Dicranum polysetum', 9.1919003, 56.045601, 14.6, 50.600000000000001, 10.0)]

注意:距离不是很近,但这可能是因为.csv 文件中没有完整的x,y 点网格。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-16
    • 2019-09-29
    • 2015-12-23
    • 2013-08-11
    • 2014-08-23
    相关资源
    最近更新 更多