如何从列内指定的列表创建子列

时间:2019-03-28 09:34:01

标签: python pandas dataframe

如何从列表中嵌套嵌套在数据框列中的列

我有一个具有值的数据框: https://laravel.com/docs/5.8/validation#using-closures

我想将消息列中的数据拆分为子列,例如

Input data

到目前为止,我已经基于逗号分割了数据

Output data

由于数据不是json格式,因此无法在其上使用json.loads。我使用下面的代码将其拆分

key = []
for i in df['text']:
i = i.replace("{", "")
i = i.replace("}", "")
for x in i.split(","):
    key.append(x.split(": "))
key[0]

给出输出 ['HashCode','“ 650e4390:0”']

在此之后,我陷入了如何以此为基础创建数据框的问题,而在{}不固定和更改后也是如此。

使用ast和json时出错

Work

由于字符串不是json,因为某些行中缺少}大括号

2 个答案:

答案 0 :(得分:2)

您还可以使用ast.literal_evalapply(pd.Series)之后的pd.concat

import ast
df['x'] = df['x'].apply(lambda x : ast.literal_eval(x))
df1 = df['x'].apply(pd.Series)
res = pd.concat([df, df1], axis=1).drop('message', axis=1)

答案 1 :(得分:0)

更有效的选择是将这些值与str.cat串联,并与read_json进行读取:

df = pd.DataFrame({'json': ['{"a": 1, "b": "foo"}', '{"a": 3, "b": "bar"}']})

x = pd.read_json(df['json'].str.cat(sep='\n'), lines=True)

print(x)

输出:

   a    b
0  1  foo
1  3  bar

与其他一些给定解决方案的性能比较:

%%timeit
pd.read_json(df['json'].str.cat(sep='\n'), lines=True)
44.2 ms ± 1.23 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

%%timeit
pd.DataFrame([json.loads(x) for x in df['json']], index=df.index)
88.9 ms ± 1.34 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

%%timeit
pd.DataFrame([ast.literal_eval(x) for x in df['json']], index=df.index)
335 ms ± 3.72 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

%%timeit
df['json'].apply(lambda x : ast.literal_eval(x)).apply(pd.Series)
6.83 s ± 212 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

在以下DataFrame上进行了性能测试:

df = pd.DataFrame({'json': ['{"a": 1, "b": 2}', '{"c": 3, "d": "z"}']*10000})