Pandas以正确的方式连接两个不同结构的JSON

2024-09-28 05:22:18 发布

您现在位置:Python中文网/ 问答频道 /正文

我知道有很多类似的问题,但我仍然觉得我在这里做错了很多事情,我相信你们中的一些人可以帮助我,给我一些未来的建议,我尝试了很多不同的方法,但仍然不能正常工作。在

我有以下两个数据来源,我想加入熊猫。在

第一个具有属性的json—我们将其称为json1:

[
{
    "propertyDetails": {
        "accountId": 102864,
        "availableFromFormatted": "On request",
        "cityName": "Derendingen",
        "contactFormTypeId": 3,
        "countryId": 1,
        "description": "Mehr erfahren: F\u00fcr weitere Bilder, Informationen zu Raumangebot, Gemeinde und Lage besuchen sie uns auf www.immostema.ch und geben Sie oben rechts im Suchfeld die Objektnummer I0398 ein. Wir freuen uns auf Sie!  \r\n  \r\n\r\n\r\n**Schauen Sie sich das Kurzvideo an:**  \r\n[https://youtu.be/xyD9oX4nmDQ](https://youtu.be/xyD9oX4nmDQ)  \r\n  \r\nIn Derendingen im Kanton Solothurn, verkaufen wir an ruhiger Wohnlage dieses **5\u00bd-Zimmer-Einfamilienhaus**(Doppeleinfamilienhaush\u00e4lfte). Das Haus, im Jahr 2013 erbaut, wurde mit qualitativ hochwertigen Materialen Innen ausgebaut. Das Haus eignet sich sehr gut f\u00fcr Familien und bietet sehr sch\u00f6nes und ruhiges Wohnen.   \r\nZum Haus geh\u00f6ren auch ein Autounterstand mit Ger\u00e4teraum sowie ein zus\u00e4tzlicher Parkplatz.   \r\n  \r\n**Hier die Eckdaten:**\r\n\r\n\r\n- Einfamilienhaus mit 5\u00bd - Zimmer\r\n- Grundst\u00fcck: 221 m\u00b2\r\n- Wohnfl\u00e4che: 141 m\u00b2\r\n- Nutzfl\u00e4che: 216 m\u00b2\r\n- Hochwertiger Innenausbau\r\n- W\u00e4rmepumpe\r\n- Fussbodenheizung\r\n- Grosse gedeckte Terrasse\r\n- Grosser Balkon\r\n- 1 Autounterstand mit grossem Ger\u00e4teraum zur Eigennutzung\r\n- 1 Parkplatz\r\n\r\n\r\n\r\nSchulen, Einkaufsm\u00f6glichkeiten, Banken, Post, erreicht man in wenigen Minuten.   \r\nBusbetrieb Solothurn und Umgebung (BSU) verkehrt im 15 Minutentakt. Die Bushaltestelle befindet sich nur 50m vom Haus entfernt.  \r\n  \r\nVerlangen Sie die detaillierte Verkaufsdokumentation.\r\n\r\n",
        "geoAccuracy": 8,
        "id": 4998203
    },
    "propertyDetailsView": {
        "accountPropertiesUrl": "/en/agency-properties/immostema-ag/102864"
    }
},
{
    "propertyDetails": {
        "accountId": 98465,
        "attributesSize": {
            "numberOfFloors": 4
        },
        "attributesSurrounding": {
            "distanceShop": 100,
            "distanceShopFormatted": "Approx. 100 m",
            "distanceKindergarten": 100,
            "distanceKindergartenFormatted": "Approx. 100 m",
            "distanceSchool1": 100,
            "distanceSchool1Formatted": "Approx. 100 m",
            "distanceSchool2": 200,
            "distanceSchool2Formatted": "Approx. 200 m",
            "distancePublicTransport": 200,
            "distancePublicTransportFormatted": "Approx. 200 m",
            "distanceMotorway": 6000,
            "distanceMotorwayFormatted": "Approx. 6000 m"
        },
        "attributes": {
            "yearBuilt": 1846
        },
        "availableFrom": "2018-05-30T00:00:00",
        "availableFromFormatted": "Immediately",
        "cityName": "Koppigen",
        "contactFormTypeId": 3,
        "countryId": 1,
        "description": " \r\n\r\n**Was es scho het**\r\n\r\n \r\n\r\nEin altehrw\u00fcrdiges Bauernhaus nahe dem Dorfzentrum.\r\n\r\n \r\n\r\n**Was es darf g\u00e4**\r\n\r\n \r\n\r\nGeplant ist ein umfassender Umbau des Bauernhauses mit der Erstellung von vier 3.5-Zimmer- und zwei 4.5-Zimmer-Wohnungen.\r\n\r\n \r\n\r\n**Me cha grad loslege, muess aber nid**\r\n\r\n \r\n\r\nDie Baubewilligung wurde bereits erteilt und ist g\u00fcltig bis Ende Dezember 2018. Der Kauf der Parzelle, inkl. aller bestehenden Bauten, ist auch ohne Realisierung des Projekts m\u00f6glich.\r\n\r\n \r\n\r\n**Meh gits hie**\r\n\r\n \r\n\r\nUnsere Verkaufsdokumentation mit detailliertem Baubeschrieb, umfassenden Planunterlagen\u00a0und vielem mehr liegt f\u00fcr Sie bereit. Gerne empfangen wir Sie auch bei uns im B\u00fcro, um Ihnen die gesamte \u00dcberbauung detailliert zu erkl\u00e4ren.\r\n\r\n \r\n\r\nIn diesem Sinne: Wir freuen uns, von Ihnen zu h\u00f6ren - bis gli!\r\n\r\n ",
        "geoAccuracy": 8,
        "id": 4998826            
    },
    "propertyDetailsView": {
        "accountPropertiesUrl": "/en/agency-properties/immosky-ag---aargau/238044"          
    }
}
]

我自己创建的第二个字典文件-将其称为json2: *备注A:如果您生成JSON文件,您是将id作为键放在字典中,还是将该键添加为“id”作为列(如果以后在pandas中使用它们)?我认为作为一个列更好,因为当pandas是一个列时,在pandas中设置_index()更容易,但不确定?在

^{pr2}$

}

在我将它们加载到pandas dataframe之前,我用我在网上找到的以下函数flattenjson1

def flatten_json(y):
out = {}

def flatten(x, name=''):
    if type(x) is dict:
        for a in x:
            if a not in ('images'):
                flatten(x[a], name + a + '_')
    elif type(x) is list:
        i = 0
        for a in x:
            flatten(a, name + str(i) + '_')
            i += 1
    else:
        out[name[:-1]] = x

flatten(y)
return out

看起来像这样:

import ijson, json
import pandas as pd

with open(json1, 'r') as f:
    #using ijson as this file might be big
    objects = ijson.items(f, 'item.propertyDetails')
    props = list(objects)

p = []
for prop in props:
    #flatten all dics/arrays inside
    p.append(flatten_json(prop))

#load into pandas including setting index:
dfprop = pd.DataFrame(p).set_index('id')

这工作很好,而且索引似乎设置正确。现在我加载第二个json2文件:

d = json.load(open(json2, 'rb'))
dfWayCalc = pd.DataFrame.from_dict(d)

dfWayCalc = dfWayCalc.transpose()  # switch cols and rows
dfWayCalc.set_index('id')

如果我想用pandas加入它,它不会给我一个错误,但是我无法从json2中找到id=4998203的正确值。它总是NaN而不是实际值。以下是我尝试的方法(多种版本之一):

m = dfprop.join(dfWayCalc, how='left')

m.loc[4998203] #doesn't show the values from json2

#if i print json2, i see the values:
print(dfWayCalc.loc['4998203'])

我做错什么了?基于索引进行这种联接的正确方法是什么? 谢谢你的帮助。在


Tags: inidjsonpandasmitimdieflatten
2条回答

考虑pandas的^{},它可以从嵌套的json数据构建数据帧,然后像任何dataframe一样合并这两个集合:

import json as json
import pandas as pd
from pandas.io.json import json_normalize

# FIRST JSON
with open('json1.json', 'r') as f:
    data = json.loads(f.read())    

df_list = [json_normalize(i['propertyDetails']) for i in data]
details_df = pd.concat(df_list, ignore_index=True)

# SECOND JSON
with open('json2.json', 'r') as f:
    data = json.loads(f.read())

df_list = [pd.DataFrame(data[i], index=[0]) for i in data]
id_df = pd.concat(df_list, ignore_index=True)

# MERGE BOTH DATAFRAMES    
final_df = pd.merge(details_df, id_df, on='id', how='left')

CodePen Output(最终数据帧的html版本)

我找到了解决办法。在

它很简单,所有列都是对象,因此无法连接。加上设置索引没有保存,因为没有重新分配给数据帧。 这是两个数据帧的协同工作:

d = json.load(open(json2, 'rb'))
dfWayCalc = pd.DataFrame.from_dict(d)

dfWayCalc = dfWayCalc.transpose()  # switch cols and rows
dfWayCalc.set_index('id')

#converting to integer was missing, all columns were type object:
dfWayCalc = dfWayCalc.apply(pd.to_numeric, errors='ignore')

#the dfWayCalc asignment was missing, so the index wasn't saved
dfWayCalc = df.set_index('id')

相关问题 更多 >

    热门问题