2015-04-21 4 views
3

У меня есть два 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') 

Я попытался создавая вложенные циклы путем итерации через файлы CSV с использованием DictReader, но он очень сильно вложен. И это займет огромное количество циклов, чтобы пройти через все это.
Кто-нибудь знает о методе?

Код, который у меня есть на данный момент, низок, но я попытался сделать цикл несколькими способами, и я ожидаю, что в моем общем подходе есть что-то принципиально неправильное.

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

С наилучшими пожеланиями, Матиас

+1

Что такое x и y в данных о климате? Lat/Lon? – reptilicus

+1

Вы изучили данные, хранящиеся в http://en.wikipedia.org/wiki/K-d_tree? Таким образом, поиск ближайшего соседа в O (log (n)) времени. –

+1

У вас есть температура для каждой .1 градуса или ваша пропавшая информация отсутствует? В первом случае задача тривиальна. –

ответ

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) 
+0

Спасибо, я более подробно рассмотрю его как можно скорее. На данный момент он выдает мне ошибку в строке 21: temp = d [x] [y] KeyError: '56 .0 ' – Mathias

+0

Хорошо, это потому, что ваша температурная сетка не завершена, как вы сказали. Отсутствуют данные. Вместо этого посмотрите в scikit Ближайшие соседи: http://scikit-learn.org/stable/modules/neighbors.html –

+0

Не может быть, что он видит 56 и 56.0 как две разные вещи? Сетка завершена, она должна быть :) – Mathias

1

Это решение, которое использует 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)] 

Примечание: не очень близкие расстояния, но это, вероятно, потому, что это не полная сетка x,y точек в файле .csv.

Смежные вопросы