我需要取消JSON数组元素的嵌套,并确保与ID列的正确映射

2024-06-28 21:56:23 发布

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

输入数据帧“df”如下(请注意“id”列中的值):

| id    | name                                                                                  |
|-------|---------------------------------------------------------------------------------------|
| a1xy  | [  {  "event": "sports",   "start": "100"},  {  "event": "lunch",  "start": "121" } ] |
| a7yz  | [  {  "event": "lunch",   "start": "109"},  {  "event": "movie",  "start": "97" } ]   |
| bx4y  | [  {  "event": "dinner",   "start": "78"},  {  "event": "sleep",  "start": "25" } ]   |

我想展平JSON数组元素,以便我的结果输出是:

| id    | name.event | name.start |
|-------|------------|------------|
| a1xy  | sports     | 100        |
| a1xy  | lunch      | 121        |
| a7yz  | lunch      | 109        |
| a7yz  | movie      | 97         |
| bx4y  | dinner     | 78         |
| bx4y  | sleep      | 25         |

“id”列中的值需要正确映射。如何在Python中执行此操作?你知道吗

我试过:

k = df.name.map(json.loads).apply(pd.DataFrame).tolist()
final_df = pd.concat(k)

但我无法映射“id”列中的值。你知道吗


Tags: 数据nameeventiddfsleepmoviestart
3条回答

也可以在apply函数中使用外部函数

import json
data=pd.DataFrame([
['a1xy',[{  "event": "sports",   "start": "100"}, {  "event": "lunch",  "start": "121" } ]],
['a7yz',[{  "event": "lunch",   "start": "109"},  {  "event": "movie",  "start": "97" }  ]],
['bx4y',[{  "event": "dinner",   "start": "78"},  {  "event": "sleep",  "start": "25" }  ]]],columns=['id','name']) 

def addtoArray(x,finalArray):
    finalArray.extend(np.insert(pd.DataFrame(x['name']).values,0,x['id'],axis=1).tolist())

finalArray=[]
data.apply(lambda x: addtoArray(x,finalArray),axis=1)
finalArray=pd.DataFrame(finalArray,columns=['col1','event','start'])
print(finalArray)

   col1   event start
0  a1xy  sports   100
1  a1xy   lunch   121
2  a7yz   lunch   109
3  a7yz   movie    97
4  bx4y  dinner    78
5  bx4y   sleep    25

您可以使用列表理解,通过id值、上次调用DataFrame构造函数展平和更新每个字典:

df['name'] = df['name'].map(json.loads)

df = pd.DataFrame([dict(y, id=i) for i, x in zip(df['id'],df['name']) for y in x])
print (df)
    event    id start
0  sports  a1xy   100
1   lunch  a1xy   121
2   lunch  a7yz   109
3   movie  a7yz    97
4  dinner  bx4y    78
5   sleep  bx4y    25

但如果输入是json,最好使用^{}。你知道吗

时间安排:

df=pd.DataFrame([
['a1xy',[{  "event": "sports",   "start": "100"}, {  "event": "lunch",  "start": "121" } ]],
['a7yz',[{  "event": "lunch",   "start": "109"},  {  "event": "movie",  "start": "97" }  ]],
['bx4y',[{  "event": "dinner",   "start": "78"},  {  "event": "sleep",  "start": "25" }  ]]],
columns=['id','name']) 
print (df)

#3k rows
df = pd.concat([df] * 1000, ignore_index=True)

In [276]: %%timeit
     ...: pd.DataFrame([dict(y, id=i) for i, x in zip(df['id'],df['name']) for y in x])
9.49 ms ± 230 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [277]: %%timeit
     ...: finalArray=[]
     ...: df.apply(lambda x: addtoArray(x,finalArray),axis=1)
     ...: pd.DataFrame(finalArray,columns=['col1','event','start'])
     ...: 
1.81 s ± 33.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

列表理解解决方案180x更快。你知道吗

假设您有json对象列表作为以下输入

data = [{'id': 'a1xy', 'name': [{'event': 'sports', 'start': '100'},{'event': 'lunch', 'start': '121'}]},
        {'id': 'a7yz', 'name': [{'event':'lunch', 'start': '109'},'event': 'movie', 'start': '97'}]},
        {'id': 'bx4y', 'name': [{'event': 'dinner', 'start': '78'},{'event': 'sleep', 'start': '25'}]}]

df = json_normalize(data, record_path='name', meta='id', record_prefix='name.')
print(df)

相关问题 更多 >