【问题标题】:Convert string of list of dictionaries to dataframe将字典列表字符串转换为数据框
【发布时间】:2019-04-28 21:46:04
【问题描述】:

这是 df1:

     indexID    detail                                             object
0          0  [{'y2': 627, 'frame': 1, 'visibility': 0, 'y1'...  Pedestrian
1          3  [{'y2': 699, 'frame': 1, 'visibility': 0, 'y1'...  Pedestrian
2          6  [{'y2': 852, 'frame': 1, 'visibility': 0, 'y1'...  Pedestrian
3          9  [{'y2': 595, 'frame': 1, 'visibility': 0, 'y1'...  Pedestrian
4         12  [{'y2': 629, 'frame': 1, 'visibility': 0, 'y1'...  Pedestrian
5         14  [{'y2': 586, 'frame': 7385, 'visibility': 0, '...  Pedestrian

仔细查看'detail'中的第一个单元格:

[{'y2': 627, 'frame': 1, 'visibility': 0, 'y1': 603, 'score': 1, 'x2': 770, 'x1': 759, 'class': 1}, {'y2': 623, 'frame': 2, 'visibility': 0, 'y1': 599, 'score': 1, 'x2': 777, 'x1': 766, 'class': 1}]

我正在尝试将 df1 转换为新数据帧,其中新数据帧的每一行对应于 df1 中字典列表的一个字典,同时保留 indexID。

假设转换数据帧的函数已经应用到df1的第一行,转换后的数据帧将如下所示:

frame   indexID x1  y1  x2  y2  score   class   visibility
  1         0   759 603 770 627   1       1          0
  2         0   766 599 777 623   1       1          0

注意事项

  • 当我将数据框打印到终端时,它显示详细信息列是字典列表,如上所示。但是,当我运行type(df1['detail'][0]) 时,它会返回<type 'str'>
  • 每行的详细信息列中的字典多于 2 个。

我试图将字符串转换为字典列表:

for index,row in df1.iterrows():
            print ast.literal_eval(row['detail'])

但是,我收到了这个错误:

Traceback (most recent call last):
  File "main.py", line 283, in <module>
    print ast.literal_eval(row['detail'])
  File "/usr/lib/python2.7/ast.py", line 80, in literal_eval
    return _convert(node_or_string)
  File "/usr/lib/python2.7/ast.py", line 79, in _convert
    raise ValueError('malformed string')
ValueError: malformed string

Link 用于 CSV

【问题讨论】:

  • 你想把[{'y2': 627, 'frame': 1, 'visibility': 0, 'y1': 603, 'score': 1, 'x2': 770, 'x1': 759, 'class': 1}, {'y2': 623, 'frame': 2, 'visibility': 0, 'y1': 599, 'score': 1, 'x2': 777, 'x1': 766, 'class': 1}]这个转换成新的df吗?如果是这样pd.DataFrame(l) 将转换?
  • @MohamedThasinah 是的!但是那个新的dataframe也需要有对应的indexID!
  • @RuvenGuna - 是从 json 创建的 DataFrame 吗?如果是,是否可以共享 json?
  • @jezrael 不是。它来自一个 csv 文件。我会将其包含在问题中。
  • @RuvenGuna - df['detail'] = df['detail'].apply(pd.io.json.loads) 工作怎么样?

标签: pandas python-2.7 dictionary dataframe


【解决方案1】:

试试这个,

t=[{'y2': 627, 'frame': 1, 'visibility': 0, 'y1': 603, 'score': 1, 'x2': 770, 'x1': 759, 'class': 1}, {'y2': 623, 'frame': 2, 'visibility': 0, 'y1': 599, 'score': 1, 'x2': 777, 'x1': 766, 'class': 1}]
ind=df['indexID'].values

new_df= pd.DataFrame(t,index=ind)
print new_df

输出:

   class  frame  score  visibility   x1   x2   y1   y2
0      1      1      1           0  759  770  603  627
3      1      2      1           0  766  777  599  623

解释:

首先从您的列表中创建一个数据框,然后在外部分配索引。

EDIT-1:

df['detail']=df['detail'].apply(lambda x: ast.literal_eval(x))
print pd.DataFrame(sum(df['detail'].values,[]),index=df['indexID'].values)

输入:

   indexID                                         detail      object
0        0     [{'y2': 627, 'frame': 1, 'visibility': 0}]  Pedestrian
1        3     [{'y2': 699, 'frame': 1, 'visibility': 0}]  Pedestrian
2        6     [{'y2': 852, 'frame': 1, 'visibility': 0}]  Pedestrian
3        9     [{'y2': 595, 'frame': 1, 'visibility': 0}]  Pedestrian
4       12     [{'y2': 629, 'frame': 1, 'visibility': 0}]  Pedestrian
5       14  [{'y2': 586, 'frame': 7385, 'visibility': 0}]  Pedestrian

输出:

    frame  visibility   y2
0       1           0  627
3       1           0  699
6       1           0  852
9       1           0  595
12      1           0  629
14   7385           0  586

【讨论】:

  • 这不起作用,因为即使当我将数据帧打印到终端时,它显示详细信息列是字典列表,但当我运行 type(df1['detail'][0]) 时,它返回 .
  • @RuvenGuna - 你可以使用ast进行转换
  • 我试过了,但我得到了一个错误。我已经更新了我的问题。
  • @RuvenGuna - 它适用于您的示例输入。请注意 Edit-1
  • @RuvenGuna - 我认为您的数据不是预期的格式。
【解决方案2】:

您可以在使用 ast.literal_eval 之前使用一些预处理 - 将 ][ 替换为 ],[ 并转换为 tuples,然后使用带有展平的列表推导:

import ast

df = pd.read_csv('test.csv', index_col=0)

df['detail'] = df['detail'].str.replace('][','],[', regex=False).apply(ast.literal_eval)
df['detail'] = [x if isinstance(x, tuple) else (x, ) for x in df['detail']]
#print (df)

s = df.set_index('indexID')['detail']
comp = {'{}_{}'.format(k, i): pd.DataFrame(x) for k, v in s.items() for i, x in enumerate(v)}
df = pd.concat(comp)
print (df.head())

       class  frame  score  visibility   x1   x2   y1   y2
0_0 0      1      1      1         0.0  759  770  603  627
    1      1      2      1         0.0  766  777  599  623
    2      1      3      1         0.0  770  786  593  618
    3      1      4      1         0.0  781  792  583  607
    4      1      5      1         0.0  786  800  573  597

【讨论】:

    猜你喜欢
    • 2020-10-28
    • 2011-07-12
    • 2014-05-23
    • 2019-05-29
    • 1970-01-01
    相关资源
    最近更新 更多