我有一本这样的字典:

{'test2':{'hi':4,'bye':3}, 'religion.christian_20674': {'path': 1, 'religious': 1, 'hi':1}}


该字典的值本身就是字典。

我的输出应如下所示:

python - 如何在python中将子字典有效地转换为矩阵-LMLPHP

我如何有效地做到这一点?

我读过this帖子,它的矩阵形状与我的不同。

this最接近我的情况,但它在字典中有一个集合,而不是另一个字典。

我的问题的不同之处在于,我还希望将内部字典的值转换为矩阵的值。

我在想这样的事情:

doc_final =[[]]
for item in dic1:
    for item2, value in dic1[item]:
        doc_final[item][item2] = value


但这不是正确的方法。

谢谢你的帮助 :)

最佳答案

在Pandas或Numpy中似乎没有任何内置的方式可以根据需要拆分行。幸运的是,您可以通过单个词典理解来做到这一点。下面显示的splitsubdicts函数提供了dict理解,而todf函数总结了整个转换过程:

def splitsubdicts(d):
    return {('%s_%d' % (k0, i + 1)):{k1:v1} for k0,v0 in d.items() for i,(k1,v1) in enumerate(v0.items())}

def todf(d):
    # .fillna(0) replaces the missing data with 0 (by default NaN is assigned to missing data)
    return pd.DataFrame(splitsubdicts(splitsubdicts(d))).T.fillna(0)


您可以这样使用todf

d = {'Test2': {'hi':4, 'bye':3}, 'religion.christian_20674': {'path': 1, 'religious': 1, 'hi':1}}
df = todf(d)
print(df)


输出:

                              bye   hi  path  religious
Test2_1_1                     0.0  4.0   0.0        0.0
Test2_2_1                     3.0  0.0   0.0        0.0
religion.christian_20674_1_1  0.0  0.0   1.0        0.0
religion.christian_20674_2_1  0.0  0.0   0.0        1.0
religion.christian_20674_3_1  0.0  1.0   0.0        0.0


如果您实际上想要一个Numpy数组,则可以轻松地转换数据框:

arr = df.values
print(arr)


输出:

[[0. 4. 0. 0.]
 [3. 0. 0. 0.]
 [0. 0. 1. 0.]
 [0. 0. 0. 1.]
 [0. 1. 0. 0.]]


您也可以将数据框转换为structured array,这样可以保留行和列标签:

arr = df.to_records()
print(arr.dtype.names)
print(arr)


输出:

('index', 'bye', 'hi', 'path', 'religious')
[('Test2_1_1', 0., 4., 0., 0.)
 ('Test2_2_1', 3., 0., 0., 0.)
 ('religion.christian_20674_1_1', 0., 0., 1., 0.)
 ('religion.christian_20674_2_1', 0., 0., 0., 1.)
 ('religion.christian_20674_3_1', 0., 1., 0., 0.)]


编辑:splitsubdicts的说明

splitsubdicts中使用的嵌套字典理解似乎有些令人困惑。确实,这只是编写嵌套循环的简写。您可以这样在几个for循环中扩展理解能力:

def splitsubdicts(d):
    ret = {}

    for k0,v0 in d.items():
        for i,(k1,v1) in enumerate(v0.items()):
            ret['{}_{}'.format(k0, i + 1)] = {k1: v1}

    return ret


此基于循环的splitsubdicts版本返回的值将与上述基于理解的版本返回的值相同。基于理解的版本might be slightly faster优于基于循环的版本,但实际上,这不是任何人都应该担心的事情。

10-06 08:46
查看更多