有条件地分配字典中的键

时间:2019-05-10 09:15:22

标签: python dictionary

我想根据某些条件在Python词典中分配一些键。可以一次性完成任务吗?

我的用例

我在pandas-dataframe中有一行,其中某些值可能是NaN或空字符串或类似内容,我想将此信息映射到dict(然后将其转换为JSON并传递给另一个应用程序)。但是,NaN不应该包含在字典中。

示例输入

我正在遍历数据帧中的行,其中示例行如下所示:

row=next(df.iterrows())

row的示例输出现在是:

a        3
b      NaN
c.x      4
c.y      5
c.z    NaN

所需的输出

{"A": 3,
"C": {"X": 4, "Y": 5}}

(对我而言)最自然的方式是这样的:

outdict={"A": row['a'] if not pandas.isna(row['a']) else None,
    "B": row['b'] if not pandas.isna(row['b']) else None,
    "C": {"X": row['c.x'] if not pandas.isna(row['c.x']) else None,
        "Y": row['c.y'] if not pandas.isna(row['c.y']) else None,
        "Z": row['c.z'] if not pandas.isna(row['c.z']) else None
}}

但是,这仍然将None分配给我想保留为空的插槽(接收应用程序在处理nulls时很困难)。

一种解决方法是使用此代码,然后在循环中删除所有None值,或者我可以对每个值使用outdict.update(如果值为NaN,则不更新)。但是这两种解决方案对我来说似乎都不是很有效。

还有更多的pythonic方法可以做到这一点吗?

2 个答案:

答案 0 :(得分:1)

要将您的DataFrame转换为不带NaN的字典,有一种简单的方法:

df.dropna().to_dict()

但是您还想从组合键创建子字典,我发现除了循环之外别无他法:

df = DataFrame({"col": [3, None, 4, 5, None]}, index=["a", "b", "c.x", "c.y", "c.z"])
d = df.dropna().to_dict()

d是:

{'col': {'a': 3.0, 'c.x': 4.0, 'c.y': 5.0}}

然后:

d2 = dict()
for k, v in d['col'].items(): 
     if k.count('.'): 
         a, b = k.split('.') 
         d2.setdefault('a', {}) 
         d2[a][b] = v 
     else: 
         d2[k] = v

d2是:

{'a': 3.0, 'c': {'y': 5.0, 'x': 4.0}}

答案 1 :(得分:0)

如果rowSeries对象,则以下代码将不会为NaN创建任何条目:

outdict = {row.index[i]: row[i]
           for i in range(data.shape[1])
           if not pandas.isna(row[i])}

但是,它不会创建您想要的嵌套结构。我有几种方法可以解决此问题,但没有一种方法非常优雅。我能想到的最好方法是在创建a.b时排除标签形式为outdict的列;

outdict = {row.index[i]: row[i]
           for i in range(data.shape[1])
           if not (pandas.isna(row[i]) or '.' in row.index[i])}

然后分别创建下标并将其分配到下标中。