Al añadir múltiples elementos para una trama de datos

Pregunta hecha: hace 9 meses Ultima actividad: hace 9 meses
up 0 down

Tengo una función que extrae una serie de variables de Zillow. He utilizado una función lambda para anexar los valores devueltos a una trama de datos. Me pregunto si hay una manera más rápida para devolver todas las variables y los añade a la trama de datos en lugar de individualmente.

Aquí está mi código:

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)

Esto actualmente no funciona debido a las nuevas columnas contendrán tanto la longitud y latitud.

2 respuestas

Quizás tu proyecto necesite tarjetas de vector libre. Nuestro sitio tiene mapas para todos los países.

Publicación patrocinada

up 0 down accepted

Tu getData función devuelve una tupla, por lo que ambas columnas tienen tanto lat y lon. Una solución podría ser para parametrizar esta función de la siguiente manera:

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

Esta no va a mejorar la eficiencia hará que sea aún más lento, sin embargo. Su cabeza principal viene de realizar llamadas de API para cada fila de la trama de datos, por lo que se ve limitada por el rendimiento de la red.

up 0 down
  • Usted puede hacer su getData función devuelve una cadena que contiene valores separados por comas de todos los elementos
  • Anexar esta cadena como csv ALL_TEXTcolumna en la trama de datos df
  • Dividir la columna ALL_TEXT en varias columnas (latitud, longitud, código postal, calle, etc.)

    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