J'ai ce fichier JSON:

{"a": [{"Name": "name1",
"number": "number1",
"defaultPrice": {"p": "232", "currency": "CAD"},
"prices": {"DZ": {"p": "62", "currency": "RMB"},
 "AU": {"p": "73", "currency": "AUD"},
"lg": "en"}},
{"Name": "name2",
"number": "number2",
 "defaultPrice": {"p": "233", "currency": "CAD"},
 "prices": {"DZ": {"p": "63", "currency": "RMB"},
 "US": {"p": "72", "currency": "USD"},
 "Lg": "en"}}]}

Maintenant, je reçois ce tableau avec le nom, le numéro, les prix par défaut, les prix, mais la colonne des prix est comme trois lignes et le prix 63 doit être lu à partir de la clé p "p": "63", "currency": "RMB".

Mais j'espère avoir un tableau avec le prix et la devise dans une colonne séparée, j'ai utilisé ceci:

Ndf = pd.concat ([pd.Series (x) pour x dans les prix], axe = 1)

Mais obtenez juste une mauvaise réponse:

 0                                                  1
 DZ           {"p": "232", "currency": "CAD"}  {"p": "62", "currency": "RMB"}
 AU           {"p": "233", "currency": "CAD"}    {"p": "63","currency":"RMB"}

Quoi qu'il en soit pour corriger cela afin que je puisse obtenir cette sortie attendue?

Name    Number   Code  currency
name1   number1   AU    AUD      
name1   number1   DZ    RMB      

Merci beaucoup!!

0
milk bear 18 mars 2019 à 23:03

2 réponses

Meilleure réponse

La chaîne json:

j = {"a": [{ "Name": "name1",
             "number": "number1",
             "defaultPrice":  {"p": "232", "currency": "CAD"},
             "prices": {"DZ": {"p": "62", "currency": "RMB"},
                        "AU": {"p": "73", "currency": "AUD"},
                        "lg": "en"
                       }
             },
            {"Name": "name2",
             "number": "number2",
             "defaultPrice":  {"p": "233", "currency": "CAD"},
             "prices": {"DZ": {"p": "63", "currency": "RMB"},
                        "US": {"p": "72", "currency": "USD"},
                        "Lg": "en"
                       }
            }
          ]}

Le code pour obtenir la sortie souhaitée:

country_codes = set()
for d in j['a']:
  c = d['prices'].keys()
  country_codes.update(c)

country_codes = sorted([i for i in country_codes if not i in ['lg','Lg']])
country_codes

meta = ['Name','number'] + [['prices',c,'p'] for c in country_codes] + [['prices',c,'currency'] for c in country_codes] 

df = json_normalize(j['a'], record_path = 'prices', meta = meta,errors='ignore')
df = df.rename(columns={0: 'countryCode'})
df = df[~df['countryCode'].isin(['lg','Lg'])]

for idx, row in df.iterrows():
    country = row['countryCode']
    col_price = df.columns[df.columns.str.contains(country+'.p')][0]
    col_currency = df.columns[df.columns.str.contains(country+'.currency')][0]
    price = row[col_price]
    currency = row[col_currency]
    df.loc[idx,'price'] = price
    df.loc[idx,'currency'] = currency

df = df[['Name','number','countryCode', 'currency', 'price']]


df

Cela donne:

    Name   number countryCode currency price
0  name1  number1          DZ      RMB    62
1  name1  number1          AU      AUD    73
3  name2  number2          DZ      RMB    63
4  name2  number2          US      USD    72
0
Bhishan Poudel 19 mars 2019 à 03:00

Vous pouvez utiliser apply(pd.Series) sur votre colonne defaultPrice pour la diviser en colonnes distinctes, puis la joindre à votre trame de données d'origine.

prices = {"a": [{"Name": "name1",
"number": "number1",
"defaultPrice": {"p": "232", "currency": "CAD"},
"prices": {"DZ": {"p": "62", "currency": "RMB"},
 "AU": {"p": "73", "currency": "AUD"},
"lg": "en"}},
{"Name": "name2",
"number": "number2",
 "defaultPrice": {"p": "233", "currency": "CAD"},
 "prices": {"DZ": {"p": "63", "currency": "RMB"},
 "US": {"p": "72", "currency": "USD"},
 "Lg": "en"}}]}

ndf = pd.DataFrame(prices['a'])
pd.concat([ndf, ndf['defaultPrice'].apply(pd.Series)], axis=1).drop('defaultPrice', axis=1)

Cependant, votre colonne prices est toujours une liste de dictionnaires. Mais puisque vous n'avez pas mentionné comment vous souhaitez gérer cela, je viens de le laisser tel quel (non inclus dans la sortie).

PRODUCTION:

Name    number  p   currency
name1   number1 232 CAD
name2   number2 233 CAD
0
panktijk 18 mars 2019 à 21:11