如何在pandas中读取和规范化以下json数据?

4

我看到了很多在stackoverflow上使用pandas读取json文件的问题,但是我仍然无法解决这个简单的问题。

数据

{"session_id":{"0":["X061RFWB06K9V"],"1":["5AZ2X2A9BHH5U"]},"unix_timestamp":{"0":[1442503708],"1":[1441353991]},"cities":{"0":["New York NY, Newark NJ"],"1":["New York NY, Jersey City NJ, Philadelphia PA"]},"user":{"0":[[{"user_id":2024,"joining_date":"2015-03-22","country":"UK"}]],"1":[[{"user_id":2853,"joining_date":"2015-03-28","country":"DE"}]]}}

我的尝试

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

# attempt1
df = pd.read_json('a.json')

# attempt2
with open('a.json') as fi:
    data = json.load(fi)
    df = json_normalize(data,record_path='user',meta=['session_id','unix_timestamp','cities'])

Both of them do not give me the required output.

需要的输出

      session_id unix_timestamp       cities  user_id joining_date country 
0  X061RFWB06K9V     1442503708  New York NY     2024   2015-03-22      UK   
0  X061RFWB06K9V     1442503708    Newark NJ     2024   2015-03-22      UK 

首选方法

https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.io.json.json_normalize.html

这是一个关于“json_normalize”函数的详细说明,该函数是用于将JSON数据规范化为扁平的表格格式。更多信息请访问以上链接。
I would love to see implementation of pd.io.json.json_normalize

pandas.io.json.json_normalize(data: Union[Dict, List[Dict]], record_path: Union[str, List, NoneType] = None, meta: Union[str, List, NoneType] = None, meta_prefix: Union[str, NoneType] = None, record_prefix: Union[str, NoneType] = None, errors: Union[str, NoneType] = 'raise', sep: str = '.', max_level: Union[int, NoneType] = None)

相关链接

5个回答

5
这里有另一种方式:
df = pd.read_json(r'C:\path\file.json')

final=df.stack().str[0].unstack()
final=final.assign(cities=final['cities'].str.split(',')).explode('cities')
final=final.assign(**pd.DataFrame(final.pop('user').str[0].tolist()))
print(final)

      session_id unix_timestamp            cities  user_id joining_date  \
0  X061RFWB06K9V     1442503708       New York NY     2024   2015-03-22   
0  X061RFWB06K9V     1442503708         Newark NJ     2024   2015-03-22   
1  5AZ2X2A9BHH5U     1441353991       New York NY     2024   2015-03-22   
1  5AZ2X2A9BHH5U     1441353991    Jersey City NJ     2024   2015-03-22   
1  5AZ2X2A9BHH5U     1441353991   Philadelphia PA     2024   2015-03-22   

  country  
0      UK  
0      UK  
1      UK  
1      UK  
1      UK  

你为什么在这里选择了 citiesuser - Jonnyboi
1
@Jonnyboi,我记不太清了,因为这已经是一年前的事情了。但从外观上看,read_json返回了一个列表,其中包含我们想要作为行的session_id和unix_timestamp。因此,我们对其进行了拆分。然后,我们将用户(也是一个列表,但我们希望它们成为列)转换为数据框并重新赋值。 - anky

3
以下是一种实现方式:
import pandas as pd

# lets say d is your json
df = pd.DataFrame.from_dict(d, orient='index').T.reset_index(drop=True)

# unlist each element
df = df.applymap(lambda x: x[0])

# convert user column to multiple cols
df = pd.concat([df.drop('user', axis=1), df['user'].apply(lambda x: x[0]).apply(pd.Series)], axis=1)

      session_id  unix_timestamp  \
0  X061RFWB06K9V      1442503708   
1  5AZ2X2A9BHH5U      1441353991   

                                         cities  user_id joining_date country  
0                        New York NY, Newark NJ     2024   2015-03-22      UK  
1  New York NY, Jersey City NJ, Philadelphia PA     2853   2015-03-28      DE 

3

我正在使用 explodejoin

s=pd.DataFrame(j).apply(lambda x : x.str[0])
s['cities']=s.cities.str.split(',')
s=s.explode('cities')
s.reset_index(drop=True,inplace=True)
s=s.join(pd.DataFrame(sum(s.user.tolist(),[])))
      session_id  unix_timestamp  ... joining_date country
0  X061RFWB06K9V      1442503708  ...   2015-03-22      UK
1  X061RFWB06K9V      1442503708  ...   2015-03-22      UK
2  5AZ2X2A9BHH5U      1441353991  ...   2015-03-28      DE
3  5AZ2X2A9BHH5U      1441353991  ...   2015-03-28      DE
4  5AZ2X2A9BHH5U      1441353991  ...   2015-03-28      DE
[5 rows x 7 columns]

2
一旦您有了df,那么您可以合并两个部分:
df = pd.read_json('a.json')
df1 = df.drop('user',axis=1)
df2 = json_normalize(df['user'])

df = df1.merge(df2,left_index=True,right_index=True)


1

我想分享一种从嵌套的json中提取数据到pandas的方法,以便未来访问者参考。在读入pandas之前,需要先提取每个列。jmespath在这里非常有用,因为它可以轻松遍历json数据:

import jmespath
from pprint import pprint
expression = jmespath.compile('''{session_id:session_id.*[],
                                  unix_timestamp : unix_timestamp.*[],
                                  cities:cities.*[],
                                  user_id : user.*[][].user_id,
                                  joining_date : user.*[][].joining_date,
                                  country : user.*[][].country
                              }''')
res = expression.search(data)
pprint(res)

{'cities': ['New York NY, Newark NJ',
            'New York NY, Jersey City NJ, Philadelphia PA'],
 'country': ['UK', 'DE'],
 'joining_date': ['2015-03-22', '2015-03-28'],
 'session_id': ['X061RFWB06K9V', '5AZ2X2A9BHH5U'],
 'unix_timestamp': [1442503708, 1441353991],
 'user_id': [2024, 2853]}

将数据读入pandas并拆分城市成单独的行:

df = (pd.DataFrame(res)
      .assign(cities = lambda x: x.cities.str.split(','))
      .explode('cities')
     )
df

session_id      unix_timestamp  cities       user_id      joining_date  country
0   X061RFWB06K9V   1442503708  New York NY     2024      2015-03-22    UK
0   X061RFWB06K9V   1442503708  Newark NJ       2024      2015-03-22    UK
1   5AZ2X2A9BHH5U   1441353991  New York NY     2853      2015-03-28    DE
1   5AZ2X2A9BHH5U   1441353991  Jersey City NJ  2853      2015-03-28    DE
1   5AZ2X2A9BHH5U   1441353991  Philadelphia PA 2853      2015-03-28    DE

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接