python dict 压平嵌套字典值以在 numpy/pandas 中创建新的键值对

问题描述 投票:0回答:1

嗨,我在下面的结构中有数据,其中我有一个键作为标签和值作为数组数组的映射,我想展平这些值并动态地将索引添加到键以创建一个新行,如下所示。我可以迭代每个键值痛苦并创建新的字典并将这些值添加到其中并获得预期的结果,但速度很慢。我的数组中有大约 50M 个值,numpy/pandas 中有更快的方法吗?

这就是我所拥有的

{'user_feature': 
array([
[ 1.33677050e-02, -1.45685431e-02], 
[-2.30765194e-02, 0.00000000e+00],
[0.00000000e+00,  0.00000000e+00],  
[1.16669689e-04,  1.33677050e-02]]), 
'sequence_service_id_list': 
array([y
[215., 215., 215., ..., 554., 215., 215.],
[215., 215., 215., ..., 215., 215., 215.],
[215., 215., 554., ..., 215., 215., 215.], 
'target_label': 
array([
1., 
1., 
1., ..., 1., 1., 1.])}

预期:

{'user_feature_1': [ 1.33677050e-02, -1.45685431e-02], 
'user_feature_2': [-2.30765194e-02, 0.00000000e+00],
'user_feature_3': [0.00000000e+00,  0.00000000e+00],
'sequence_service_id_list_1': [215., 215., 215., ..., 554., 215., 215.],
'sequence_service_id_list_2': [215., 215., 215., ..., 215., 215., 215.],
'sequence_service_id_list_3': [215., 215., 554., ..., 215., 215., 215.], 
'target_label_1': 1., 
'target_label_2': 1., 
'target_label_3': 1., 
}
python pandas numpy numpy-ndarray
1个回答
0
投票

这不是创建所需字典的矢量化解决方案,而是一种使用遵循新格式的键访问所需行的方法。

让我们定义一个类来包装这个输入字典。当您尝试从此类的对象获取键时,将调用

__getitem__
方法,其中键被解析为其“原始键”和“索引”组件,并返回相应值的相应行。

class CustomDict:
    def __init__(self, input_dict):
        self.__data = input_dict

    def __getitem__(self, key):
        orig_key, elem_index = key.rsplit("_", 1)
        return self.__data[orig_key][int(elem_index)-1]

让我们测试一下:

array = np.array

inp_dict = {'user_feature': array([[ 1.33677050e-02, -1.45685431e-02], 
                                   [-2.30765194e-02, 0.00000000e+00],
                                   [0.00000000e+00,  0.00000000e+00],  
                                   [1.16669689e-04,  1.33677050e-02]]), 
            'sequence_service_id_list': array([[215., 215., 215., 554., 215., 215.],
                                               [215., 215., 215., 215., 215., 215.],
                                               [215., 215., 554., 215., 215., 215.]]), 
            'target_label': array([1., 1., 1., 1., 1., 1.])}

cus_dict = CustomDict(inp_dict)

print(cus_dict['user_feature_1'])
# [ 0.01336771 -0.01456854]

print(cus_dict['user_feature_2'])
# [-0.02307652  0.        ]

print(cus_dict['user_feature_3'])
# [0. 0.]

由于您从不迭代任何内容,并且拆分键是在访问时发生的简单、快速的操作,因此这比创建新字典要快得多。

您还可以实现类似的

__setitem__
方法来设置原始字典的元素:

def __setitem__(self, key, value):
    orig_key, elem_index = key.rsplit("_", 1)
    self.__data[orig_key][elem_index] = value
© www.soinside.com 2019 - 2024. All rights reserved.