Python 从目录中的列表中删除词典

Python 从目录中的列表中删除词典,python,dictionary,pandas,Python,Dictionary,Pandas,我有dataframe,其中一列是字典列表,它存储为字符串,如下所示: name age misc Jim 44 "[{"value":3,"type":"cars"},{"value":1,"type":"pets"},{"value":13,"type":"shoes"}]" Bob 25 "[{"value":3,"type":"siblings"},{"value":1,"type":"pets"}]" Sue 55 "[]" 我想讲到这一点,即每种类型都成为它自己的列,并

我有dataframe,其中一列是字典列表,它存储为字符串,如下所示:

name age misc
Jim  44  "[{"value":3,"type":"cars"},{"value":1,"type":"pets"},{"value":13,"type":"shoes"}]"
Bob  25  "[{"value":3,"type":"siblings"},{"value":1,"type":"pets"}]"
Sue  55  "[]"
我想讲到这一点,即每种类型都成为它自己的列,并具有相应的值:

name age cars pets shoes siblings
Jim  44  3    1    13    0
Bob  25  0    1    0     3
Sue  55  0    0    0     0

我真的会在这里读到:。另外,您的数据源必须遍布各地,我将首先对其进行重新格式化。由于您没有提供数据本身的原始源,下面是一个创建数据框架的简单示例,您正在寻找一个更结构化的数据源:

>>> data = {'Bob':{'age':25, 'pets':1, 'siblings':3}, 'Jim':{'age':44, 'cars':3, 'pets': 1, 'shoes': 13}}
>>> pd.DataFrame(data).T.fillna(0)

     age  cars  pets  shoes  siblings
Bob   25     0     1      0         3
Jim   44     3     1     13         0

最好避免创建一个数据框,其中的列的值是 格言。但为了帮助你做到这一点,我们需要了解 用于构建当前数据帧的数据

但是,给定当前数据帧,您可以将其转换为所需的数据帧 使用df['misc']的数据帧。应用(func)在每个
df['misc']
中的值

如果安排此函数返回序列,则
df['misc'].apply(func)
将返回一个数据帧,其列对应于系列的索引。比如说,

def func(x):
    try:
        df = pd.DataFrame(ast.literal_eval(x))
        result = pd.Series(df['value'].values, index=df['type'])
    except KeyError:
        result = pd.Series()
    return result

attributes = df['misc'].apply(func)
print(attributes)
屈服

   cars  pets  shoes  siblings
0     3     1     13       NaN
1   NaN     1    NaN         3
2   NaN   NaN    NaN       NaN
  name  age  cars  pets  shoes  siblings
0  Jim   44     3     1     13         0
1  Bob   25     0     1      0         3
2  Sue   55     0     0      0         0
现在我们可以用0替换NAN:

attributes = attributes.fillna(0)
df
中删除
misc
列:

del df['misc']
并通过将
df
属性连接来构建所需的数据帧:

df = pd.concat([df, attributes], axis=1)

总而言之

import numpy as np
import pandas as pd
import ast

df = pd.DataFrame(
    [('Jim', 44, '''[{"value":3,"type":"cars"},{"value":1,"type":"pets"}, {"value":13,"type":"shoes"}]'''),
     ('Bob', 25, '[{"value":3,"type":"siblings"},{"value":1,"type":"pets"}]'),
     ('Sue', 55, '[]')],
    columns=['name', 'age', 'misc'])

def func(x):
    try:
        df = pd.DataFrame(ast.literal_eval(x))
        result = pd.Series(df['value'].values, index=df['type'])
    except KeyError:
        result = pd.Series()
    return result

attributes = df['misc'].apply(func)
attributes = attributes.fillna(0)
del df['misc']
df = pd.concat([df, attributes], axis=1)
print(df)
屈服

   cars  pets  shoes  siblings
0     3     1     13       NaN
1   NaN     1    NaN         3
2   NaN   NaN    NaN       NaN
  name  age  cars  pets  shoes  siblings
0  Jim   44     3     1     13         0
1  Bob   25     0     1      0         3
2  Sue   55     0     0      0         0

步骤1:将字符串“列表”列转换为实际列表:

from ast import literal_eval 

df['misc'] = [literal_eval(r) for r in df.misc] 
步骤2:循环浏览每个字典以获取“值”(如汽车、宠物、鞋子等)。为每个唯一值向DataFrame添加一列

sublists = [[d.get('type') for d in cell] for cell in df.misc]
cols = list(set([item for sublist in sublists for item in sublist]))
for c in cols:
    df[c] = 0
步骤3:创建一个字典,获取每种类型的值(假设行中给定字典列表的类型不超过一种)。然后枚举这些值计数并将结果分配回数据帧:

value_counts = [{d.get('type'): d.get('value') for d in cell} for cell in df.misc]
for n, row in enumerate(value_counts):
if row:
    items, values = zip(*row.items())
    df.loc[df.index[n], items] = values

del df['misc']

>>> df
  name  age  cars  shoes  pets  siblings
0  Jim   44     3     13     1         0
1  Bob   25     0      0     1         3
2  Sue   55     0      0     0         0

这工作得很好,但是当我在我的集合上尝试它时(格式相同),我得到一个错误:
PandasError:DataFrame构造函数没有正确调用听起来misc列包含字符串。从原始数据正确地构建所需的数据帧,而不是千方百计地修复当前数据帧,这确实是更好的做法,但是如果必须这样做,则可以使用
ast.literal\u eval
将字符串转换为dict列表。我编辑了这篇文章来展示它是如何实现的。这似乎很有希望,问题是我现在发现每一个实际上都是字符串,所以它实际上是这样的:
“[{“value”:3,“type”:“cars”},{“value”:1,“type”:“pets”},{“value”:13,“type”:“shoes”}”
你可以使用literal\u eval:from ast import literal\u eval df['misc']=[df.misc中r的文字值(r)]