Добавление нескольких элементов в фрейм данных - PullRequest
0 голосов
/ 22 января 2019

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

Вот мой код:

from xml.dom.minidom import parse,parseString
import xml.dom.minidom
import requests
import sys
import pandas as pd
import numpy as np

l_zwsid='' 

df = pd.read_csv('data.csv')

def getElementValue(p_dom,p_element):
    if len(p_dom.getElementsByTagName(p_element)) > 0:
       l_value=p_dom.getElementsByTagName(p_element)[0]
       return(l_value.firstChild.data)
    else:
       l_value='NaN'
       return(l_value)

def getData(l_zwsid, a_addr, a_zip):
    try:
        l_url='http://www.zillow.com/webservice/GetDeepSearchResults.htm?zws-id='+l_zwsid+'&address='+a_addr+'&citystatezip='+a_zip
        xml=requests.get(l_url)
        dom=parseString(xml.text)

        responses=dom.getElementsByTagName('response')

        zpid=getElementValue(dom,'zpid')
        usecode=getElementValue(dom,'useCode')
        taxyear=getElementValue(dom,'taxAssessmentYear')
        tax=getElementValue(dom,'taxAssessment')
        yearbuilt=getElementValue(dom,'yearBuilt')
        sqft=getElementValue(dom,'finishedSqFt')
        lotsize=getElementValue(dom,'lotSizeSqFt')
        bathrooms=getElementValue(dom,'bathrooms')
        bedrooms=getElementValue(dom,'bedrooms')
        totalrooms=getElementValue(dom,'totalRooms')
        lastSale=getElementValue(dom,'lastSoldDate')
        lastPrice=getElementValue(dom,'lastSoldPrice')
        latitude=getElementValue(dom, 'latitude')
        longitude=getElementValue(dom, 'longitude')

        for response in responses:
            addresses=response.getElementsByTagName('address')
            for addr in addresses:
                street=getElementValue(addr,'street')
                zipcode=getElementValue(addr,'zipcode')

            zestimates=response.getElementsByTagName('zestimate')
            for zest in zestimates:
                amt=getElementValue(zest,'amount')
                lastupdate=getElementValue(zest,'last-updated')
                valranges=zest.getElementsByTagName('valuationRange')
                for val in valranges:
                    low=getElementValue(val,'low')
                    high=getElementValue(val,'high')
        return longitude, latitude
    except AttributeError:
        return None

df['Longtitude'] = df.apply(lambda row: getData(l_zwsid, row['Street'], row['Zip']), axis = 1)
df['Latitude'] = df.apply(lambda row: getData(l_zwsid, row['Street'], row['Zip']), axis = 1)

В настоящее время это не работает, поскольку новые столбцы будут содержать как долготу, так и широту.

Ответы [ 2 ]

0 голосов
/ 23 января 2019
  • Вы можете сделать так, чтобы ваша getData функция возвращала строку, содержащую разделенные запятыми значения всех элементов
  • Добавить эту строку CSV как ALL_TEXT столбец в кадре данных df
  • Разделить столбец ALL_TEXT на несколько столбцов (Lat, long, почтовый индекс, улица и т. Д.)

    def split_into_columns(text):
    
        required_columns = ['Latitude', 'Longtitude', 'Zipcode']
        columns_value_list = text['ALL_TEXT'].split(',')
        for i in range(len(required_columns)):
        text[required_columns[i]] = columns_value_list[i]
    
        return text
    
    df= pd.DataFrame([ ['11.49, 12.56, 9823A'], ['14.02, 15.29, 9674B'] ], columns=['ALL_TEXT'])  
    
    updated_df = df.apply(split_into_columns, axis=1)
    

DF

    ALL_TEXT
0   11.49, 12.56, 9823A
1   14.02, 15.29, 9674B

updated_df

   ALL_TEXT              Latitude  Longtitude Zipcode
0   11.49, 12.56, 9823A  11.49     12.56       9823A
1   14.02, 15.29, 9674B  14.02     15.29       9674B
0 голосов
/ 22 января 2019

Ваша функция getData возвращает кортеж, поэтому оба столбца имеют значения как lat, так и lon.Одним из обходных путей может быть параметризация этой функции следующим образом:

def getData(l_zwsid, a_addr, a_zip, axis='lat'):
    valid = ['lat', 'lon']
    if axis not in valid:
        raise ValueError(f'axis must be one of {valid}')
    ...
    if axis == 'lat':
        return latitude
    else:
        return longitude

Это не повысит эффективность , однако сделает ее еще медленнее.Ваши основные накладные расходы связаны с выполнением вызовов API для каждой строки в DataFrame, поэтому вы ограничены производительностью сети.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...