pandas:当值是可变长度的集合或列表时,从字典创建一个长/整洁的 DataFrame

Gio*_*oni 6 python pandas unnest

简单字典:

d = {'a': set([1,2,3]), 'b': set([3, 4])}
Run Code Online (Sandbox Code Playgroud)

(如果重要的话,这些集合可能会变成列表)

我如何将它转换成一个长/整齐DataFrame,其中每一列都是一个变量,每个观察都是一行,即:

  letter  value
0      a      1
1      a      2
2      a      3
3      b      3
4      b      4
Run Code Online (Sandbox Code Playgroud)

以下工作,但有点麻烦:

id = 0
tidy_d = {}
for l, vs in d.items():
    for v in vs:
        tidy_d[id] = {'letter': l, 'value': v}
        id += 1
pd.DataFrame.from_dict(tidy_d, orient = 'index')
Run Code Online (Sandbox Code Playgroud)

有什么pandas魔法可以做到这一点吗?就像是:

pd.DataFrame([d]).T.reset_index(level=0).unnest()
Run Code Online (Sandbox Code Playgroud)

这里unnest显然不存在,来自R.

jpp*_*jpp 3

itertools.chain您可以使用and进行理解zip

from itertools import chain

keys, values = map(chain.from_iterable, zip(*((k*len(v), v) for k, v in d.items())))

df = pd.DataFrame({'letter': list(keys), 'value': list(values)})

print(df)

  letter  value
0      a      1
1      a      2
2      a      3
3      b      3
4      b      4
Run Code Online (Sandbox Code Playgroud)

可以用更易读的方式重写:

zipper = zip(*((k*len(v), v) for k, v in d.items()))
values = map(list, map(chain.from_iterable, zipper))

df = pd.DataFrame(list(values), columns=['letter', 'value'])
Run Code Online (Sandbox Code Playgroud)