Python 基于dataframe中的值从字典中删除嵌套的键值对

Python 基于dataframe中的值从字典中删除嵌套的键值对,python,pandas,dictionary,Python,Pandas,Dictionary,问题是一部分帮助一部分好奇,所以我有一个dict,一旦我的所有条件都经过迭代,我会将它添加到一个列表中: for col, row in df.iterrows(): up_list = [] if row['id_check'] == 'Add all': l = {'external': {'om': {'id' : row['posm']}, 'wd': {'id': row

问题是一部分帮助一部分好奇,所以我有一个dict,一旦我的所有条件都经过迭代,我会将它添加到一个列表中:

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'的值之一,我不想将整个键值对添加到字典中

因此,最佳情况输出如下所示:

final_l = {'external': {'om': {'id' : '123'},
                        'wd': {'id': '456'},
                        'wk': {'id': '789'}
                                }}
但是:如果根据其相应的数据帧值提供其中一个值,我不想将“id”替换为“None”,我根本不想将其放在那里,因此理想情况下,假设
'wk'='None'
,那么输出dict将如下所示:

final_l = {'external': {'om': {'id' : '123'},
                        'wd': {'id': '456'}
                                }}
但我唯一能得到的是:

final_l = {'external': {'om': {'id' : '123'},
                        'wd': {'id': '456'},
                        'wk': {'id': 'None'}
                                }}
这对于我的用例来说不是最佳的。那么,如何根据字典对应的数据帧值从字典中删除(甚至不添加)特定的键值对呢?另外,如果有更好的方法,我很乐意接受,因为这“有效”,但上帝保佑,这并不优雅

编辑示例数据帧:

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

我编辑我以前的答案是基于您的回答,即您试图修改字典而不是数据帧,并且因为我以前的答案不正确

我找不到一种简单的方法来满足您的要求-例如列表理解,但我创建了一个转换器:

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']}

我编辑我以前的答案是基于您的回答,即您试图修改字典而不是数据帧,并且因为我以前的答案不正确

我找不到一种简单的方法来满足您的要求-例如列表理解,但我创建了一个转换器:

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,您可以尝试使用
来记录
dropna
eq
来记录

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()
输出:

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

IIUC,您可以尝试使用
来记录
dropna
eq
来记录

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()
输出:

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'}}}
并忽略值==
无的键:

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

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

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'}}}
并忽略值==
无的键:

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


你能添加一个数据帧的示例吗?@MrNobody33编辑了这篇文章,在它下面是示例df。另一个例子是
“add_all”
?我的意思是,如果
行['id\u check']!='是否添加所有“
@SebastianGoslin@MrNobody33
addnone
这是一个传递,我在这个循环中创建的字典的特定部分不会被附加。准备好了,只添加了一个方法@SebastianGoslin!你能添加一个数据帧的示例吗?@MrNobody33编辑了这篇文章,在它下面是示例df。另一个例子是
“add_all”
?我的意思是,如果
行['id\u check']!='是否添加所有“
@SebastianGoslin@MrNobody33
addnone
这是一个传递,我在这个循环中创建的字典的特定部分不会被附加。准备好了,只添加了一个方法@SebastianGoslin!因此,完整的数据帧有几百行,将整个内容放在这里是不切实际的。但是如果我读对了你写的内容,它将删除所有
==None
的行,在这种情况下,这不是最佳的,因为有些值可以有所有的
id
s,或者有一些,或者没有,它是不同的。是的,但是你可以将其合并到我说的内容中。您可以使用一个函数来检查不需要的类型和值。然后你会得到类似于
{i:j代表i,j在d.items()中如果不是错误的值(j)}
,其中
是错误的值()
是函数。也就是说,除非我误解了你所说的“一些值可以有所有的ID,或者一些,或者没有,它是变化的”。啊,我明白了,所以示例df有一行可能出现的所有值。但是在实际的df中,有几千行,其中一些行可能对每一列都有合适的值,而另一些行可能没有,因此在整个数据帧中它是不一致的。因此,我想创建一个字典,它的格式与我在数据帧中出现的值(不是
None
)的问题上所做的格式相同。我已经更新了示例,希望它更有意义。在您最近的编辑之前,您似乎在使用pd dataframe构造函数中的数据字段来初始化它。我的印象是,这个问题是基于实例创建的——但是如果您已经有了df,那么我认为最好/最具python风格的做法是使用pandas提供的实际api。也就是说,
df.dropna
。可以找到更多信息。因此,完整的数据帧有几百行,将整个内容放在这里是不切实际的。但是如果我读对了你写的内容,它将删除所有
==None
的行,在这种情况下,这不是最佳的,因为有些值可以有所有的
id
s,或者有一些,或者没有,它是不同的。是的,但是你可以将其合并到我说的内容中。您可以使用一个函数来检查不需要的类型和值。然后你会得到类似于
{i:j代表i,j在d.items()中如果不是错误的值(j)}
,其中
是错误的值()
是函数。也就是说,除非我误解了你所说的“一些值可以有所有的ID,或者一些,或者没有,它是变化的”。啊,我明白了,所以示例df有一行可能出现的所有值。但在实际的df中,有几千行,其中一些行的每一列都有合适的值,而另一些行可能没有,因此在整个dat中它是不一致的