Я пытаюсь написать скрипт Python, который будет принимать любой CSV-файл, запускать его через геокодер, а затем записывать полученные атрибуты геокодирования (+ все данные из исходного файла) в новый CSV-файл.
На данный момент мой код следующий, и я должен отметить, что все работает должным образом, за исключением объединения атрибутов геокодирования с данными в необработанном CSV-файле.В настоящее время происходит то, что все значения полей исходного файла CSV для конкретной строки представлены как одно значение в файле CSV (хотя атрибуты геокодирования отображаются правильно).Проблема со скриптом находится ближе к концу.Я упустил код для различных классов для краткости.
Я должен также отметить, что я использую hasattr *, потому что хотя я не знаю, какие поля находятся в исходном файле in_file, я знаю, что где-то ввходной CSV эти поля будут присутствовать, и это поля, необходимые для геокодирования.
Первоначально я попытался изменить "new_file.writerow ([])" на "new_file.writerow ()", на этом этапестрока ввода -r- правильно записала файл CSV, но атрибуты геокодирования больше не могли быть записаны в CSV, поскольку они рассматривались как дополнительные аргументы.
def locate(file=None):
""" locate by geocoding func"""
start_time = time.time()
count = 0
if file != None:
with open (file) as in_file:
f_csv = csv.reader(in_file)
# regex headers and lowercase to standarize for hasattr func.
headers = [ re.sub('["\s+]', '_', h).lower() for h in next(f_csv)]
# Used namedtuple for headers
Row = namedtuple('Row', headers)
# for row in file
for r in f_csv:
count += 1
# set row values to named tuple values
row = Row(*r)
# Try hasattr to find fields names address, city, state, zipcode
if hasattr(row, 'address'):
address = row.address
elif hasattr(row, 'address1'):
address = row.address1
if hasattr(row, 'city'):
city = row.city
if hasattr(row, 'state'):
state = row.state
elif hasattr(row, 'st'):
state = row.st
if hasattr(row, 'zipcode'):
zipCode = row.zipcode
elif hasattr(row, 'zip'):
zipCode = row.zipcode
# Create new address object
addressObject = Address(address, city, state, zipCode)
# Get response from api
data = requests.get(addressObject.__str__()).json()
try:
data['geocodeStatusCode'] = int(data['geocodeStatusCode'])
except:
data['geocodeStatusCode'] = None
if data['geocodeStatusCode'] == 'SomeNumber':
# geocoded address ideally uses parent class attributes
geocodedAddressObject = GeocodedAddress(addressObject.address, addressObject.city, addressObject.state, addressObject.zipCode, data['addressGeo']['latitude'], data['addressGeo']['longitude'], data['addressGeo']['score'])
else:
geocodedAddressObject = GeocodedAddress(addressObject.address, addressObject.city, addressObject.state, addressObject.zipCode)
# Problem Area
geocoded_file = file.replace('.csv', '_geocoded2') + '.csv'
with open(geocoded_file, 'a', newline='') as geocoded:
# Problem area -- the r -row- attribute writes all within the same cell even though they are comma separated. The geocoding attributes do write correctly to the csv file
new_file = csv.writer(geocoded)
new_file.writerow([r, geocodedAddressObject.latitude, geocodedAddressObject.longitude, geocodedAddressObject.geocodeScore])
print('The time to geocode {} records: {}'.format(count, (time.time() - start_time)))
Пример входных данных CSV:
"UID", "Occupant", "Address", "City", "State", "ZipCode"
"100001", "Playstation Theater", "New York", "NY", "10036"
"100002", "Ed Sullivan Theater", "New York, "NY", "10019"
Пример вывода CSV (дополнительные поля анализируются во время геокодирования)
"UID", "Occupant", "Address", "City", "State", "ZipCode", "GeoCodingLatitude", "GeoCodingLongitude", "GeoCodingScore"
"100001", "Playstation Theater", "New York", "NY", "10036", "45.1234", "-110.4567", "100"
"100002", "Ed Sullivan Theater", "New York, "NY", "10019", "44.1234", "-111.4567", "100"