Python 从目录中的列表中删除词典
我有dataframe,其中一列是字典列表,它存储为字符串,如下所示: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 "[]" 我想讲到这一点,即每种类型都成为它自己的列,并
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)]