Python 熊猫:从键:值对的字符串重建数据帧

Python 熊猫:从键:值对的字符串重建数据帧,python,pandas,dataframe,Python,Pandas,Dataframe,假设我有以下数据集: 0 0 foo:1 bar:2 baz:3 1 bar:4 baz:5 2 foo:6 因此,每一行本质上都是一个序列化为字符串的dict,其中key:value对由空格分隔。每行中有数百个key:value对,而唯一键的数量只有几千个。可以说,数据是稀疏的 我想要的是一个漂亮的数据帧,其中键是列,值是单元格。缺少的值将替换为零。像这样: foo bar baz 0 1 2 3 1 0 4 5 2 6 0 0 我知道我可以将字

假设我有以下数据集:

  0
0 foo:1 bar:2 baz:3
1 bar:4 baz:5
2 foo:6
因此,每一行本质上都是一个序列化为字符串的dict,其中
key:value
对由空格分隔。每行中有数百个
key:value
对,而唯一键的数量只有几千个。可以说,数据是稀疏的

我想要的是一个漂亮的数据帧,其中键是列,值是单元格。缺少的值将替换为零。像这样:

  foo bar baz
0   1   2   3
1   0   4   5
2   6   0   0
我知道我可以将字符串拆分为键:值对:

In: frame[0].str.split(' ')
Out:
  0
0 [foo:1, bar:2, baz:3]
1 [bar:4, baz:5]
2 [foo:6]
但是接下来呢


编辑:我在AzureML Studio环境中运行。因此,效率很重要。

您可以尝试列表理解,然后使用
0
创建新的
DataFrame

s = df['0'].str.split(' ')

d = [dict(w.split(':', 1) for w in x) for x in s]
print d
#[{'baz': '3', 'foo': '1', 'bar': '2'}, {'baz': '5', 'bar': '4'}, {'foo': '6'}]

print pd.DataFrame.from_records(d).fillna(0)
#  bar baz foo
#0   2   3   1
#1   4   5   0
#2   0   0   6
编辑:


如果在函数
中使用,则可以从_记录
参数索引和

print df
                               0
0              foo:1 bar:2 baz:3
1                    bar:4 baz:5
2                          foo:6
3  foo:1 bar:2 baz:3 bal:8 adi:5

s = df['0'].str.split(' ')
d = [dict(w.split(':', 1) for w in x) for x in s]
print d
[{'baz': '3', 'foo': '1', 'bar': '2'}, 
 {'baz': '5', 'bar': '4'}, 
 {'foo': '6'}, 
 {'baz': '3', 'bal': '8', 'foo': '1', 'bar': '2', 'adi': '5'}]
如果最长的
字典
具有所有键,这些键将创建所有可能的列:

cols = sorted(d, key=len, reverse=True)[0].keys()
print cols
['baz', 'bal', 'foo', 'bar', 'adi']

df = pd.DataFrame.from_records( d, index= df.index, columns=cols )
df = df.fillna(0)

print df
  baz bal foo bar adi
0   3   0   1   2   0
1   5   0   0   4   0
2   0   0   6   0   0
3   3   8   1   2   5
EDIT2:如果最长的
字典
不包含所有键,并且键位于其他字典中,请使用:

list(set( val for dic in d for val in dic.keys()))
样本:

print df
                               0
0            foo1:1 bar:2 baz1:3
1                    bar:4 baz:5
2                          foo:6
3  foo:1 bar:2 baz:3 bal:8 adi:5

s = df['0'].str.split(' ')
d = [dict(w.split(':', 1) for w in x) for x in s]

print d
[{'baz1': '3', 'bar': '2', 'foo1': '1'}, 
 {'baz': '5', 'bar': '4'}, 
 {'foo': '6'}, 
 {'baz': '3', 'bal': '8', 'foo': '1', 'bar': '2', 'adi': '5'}]

cols =  list(set( val for dic in d for val in dic.keys()))
print cols 
['bar', 'baz', 'baz1', 'bal', 'foo', 'foo1', 'adi']

df = pd.DataFrame.from_records( d, index= df.index, columns=cols )
df = df.fillna(0)

print df
  bar baz baz1 bal foo foo1 adi
0   2   0    3   0   0    1   0
1   4   5    0   0   0    0   0
2   0   0    0   0   6    0   0
3   2   3    0   8   1    0   5

谢谢你的解决方案。它看起来真的很有前途,很直截了当。不幸的是,我在AzureML Studio中作为一个Jupyter笔记本运行这个程序,看起来我达到了极限。内核在最后一步中崩溃或暂停。数据帧。从_记录(d)。fillna(0)
索引
参数显著提高了性能。非常感谢。很高兴能帮助你!祝你好运