繁体   English   中英

根据 dataframe 中的值从字典中删除嵌套键值对

[英]Removing a nested key value pair from dictionary based on value in dataframe

问题一方面帮助一方面帮助好奇心,所以我有一个字典,一旦我的所有条件都被迭代,我就会将它附加到一个列表中:

for col, row in df.iterrows():
    up_list = []

    if row['id_check'] == 'Add all':
    
        l = {'external': {'om': {'id' : row['posm']},
                                    'wd': {'id': row['wdp']},
                                    'wk': {'id': row['tw'].replace('ru: ', '')}
                                    }
                 }

         up_list.append(l)

基本上,我正在向 dict l 添加多个键和值,我的主要问题是,提供'id' == 'None'的值之一我不想将整个键值对添加到字典中。

所以最好的情况 output 看起来像:

final_l = {'external': {'om': {'id' : '123'},
                        'wd': {'id': '456'},
                        'wk': {'id': '789'}
                                }}

但是:根据相应的 dataframe 值提供其中一个值== 'None' ,我不想用 None 替换 'id',我根本不想在那里,所以理想情况下说'wk' == 'None'那么 output 字典看起来像:

final_l = {'external': {'om': {'id' : '123'},
                        'wd': {'id': '456'}
                                }}

但我唯一能得到的是:

final_l = {'external': {'om': {'id' : '123'},
                        'wd': {'id': '456'},
                        'wk': {'id': 'None'}
                                }}

这对我的用例来说不是最佳的。 那么,如何根据对应的 dataframe 值从字典中删除(甚至不添加)特定键值对? 此外,如果有更好的方法可以做到这一点,我非常愿意接受,因为这“有效”,但上帝不优雅。

编辑样本 Dataframe:

   id_check   om    wd    wk
0   Add all  123  None   789
1   Add all  472   628  None
2  Add None  528   874   629

我正在根据您尝试更改字典而不是 dataframe 的回复来编辑我之前的答案,因为我之前的答案不正确。

我找不到一种方法来使用一种简单的方法来完成您所要求的事情 - 例如列表理解,但能够使用我创建的这个转换器来做到这一点:

class Converter:
    
    def __init__(self):
        self.rows = []
        self.cols = []
    
    @classmethod
    def from_dict(cls, d):
        conv_df = cls()
        conv_df.cols = list(d.keys())
        conv_df.rows = list(zip(*d.values()))
        return conv_df

    def as_dict(self):
        vals = []
        
        for idx, _ in enumerate(self.cols):
            vals.append([j[idx] for j in self.rows if None not in j])
        return {k: v for k, v in zip(self.cols, vals)

示例用法:

>>> z = {'a': [1, 2, 3], 'b': ['a', 'b', 'c'], 'c': ['q', 'r', None]}
>>> conv = Converter.from_dict(z)
>>> conv.cols
['a', 'b', 'c']
>>> conv.rows
[(1, 'a', 'q'), (2, 'b', 'r'), (3, 'c', None)]
>>> "Get as dict and we expect last row not to appear in it:"
'Get as dict and we expect last row not to appear in it:'
>>> conv.as_dict()
{'a': [1, 2], 'b': ['a', 'b'], 'c': ['q', 'r']}

IIUC,您可以尝试使用to_dictdropnaeqto_list

final_l=df[df['id_check'].eq('Add all')].drop('id_check',1)
                         .apply(lambda x : {'external':x.dropna().to_dict()},axis=1)
                         .to_list()

Output:

final_l
[{'external': {'om': 123.0, 'wk': '789'}},
 {'external': {'om': 472.0, 'wd': '628'}}]

所以我尝试了提供的答案,我遇到的最大问题是真相评估和速度。 我编写了这个“有效”的代码,但从效率的角度来看我不太满意:

if row['id_check'] == 'Add all IDs':
        
        link_d, ex_link = {}, {}
        if row['posm'] != 'None':
            link_d['om'] = {'id': row['posm']}
        if row['pd'] != 'None':
            link_d['wd'] = {'id': row['pd']}
        if row['tw'] != 'None':
            link_d['wk'] = {'id': row['tw']}
            
        ex_link['external'] = link_d
        up_list.append(ex_link)
    
    up_d[row['id']] = up_list
    all_list.append(up_d)

哪个输出:

{'external': {'om': {'id' : '123'},
                     'wd': {'id': '456'},
                     'wk': {'id': '789'}}}

并忽略 value == None的键:

{'external': {'om': {'id' : '123'},
                     'wd': {'id': '456'}}}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM