从字典键和值填充数据框

4

我有以下数据框作为示例。

df_test = pd.DataFrame(data=None, index=["green","yellow","red","pink"], columns=["bear","dog","cat"], dtype=None, copy=False)

enter image description here

我有一个字典,其中键和值与我的数据帧的索引和列相同或相关。

d = {"green":["bear","dog"], "yellow":["bear"], "red":["bear"]}

我希望根据提供的键和值填充我的数据框,如果键不存在,则希望填充为空。
期望输出

enter image description here

我只能想到使用列表和循环。有没有简单的方法来实现这个?或者有什么函数可以帮助我吗?

3个回答

4

使用字典和集合的循环,将True值替换所有缺失的行,并通过mask函数将其替换为空(Empty),最后再使用fillna函数替换缺失值:

for k, v in d.items():
    for x in v:
        df_test.loc[k, x] = 'Yes'

df_test = df_test.mask(df_test.isnull().all(axis=1), 'Empty').fillna('No')
print (df_test)
         bear    dog    cat
green     Yes    Yes     No
yellow    Yes     No     No
red       Yes     No     No
pink    Empty  Empty  Empty

1
@may - 解决方案已经修改,请您检查一下。 - jezrael
1
谢谢!我觉得现在可以了!我很快会接受它 :) - may
1
@may - 你认为字典中应该是空列表还是NaN值? - jezrael
1
对我来说,它很好用,没有最后一行是粉红色的。问题出在真实数据上吗?还是样本也有问题? - jezrael
1
只有您的作品!抱歉,这是我问题的最佳答案 :D - may
显示剩余5条评论

2

以下是一种主要使用pd.get_dummiespd.DataFrame.reindex的向量化解决方案:

df = pd.DataFrame.from_dict(d, orient='index')

res = pd.get_dummies(df.reindex(df_test.index), prefix='', prefix_sep='')\
        .reindex(columns=df_test.columns)\
        .fillna(0).applymap({0: 'No', 1: 'Yes'}.get)\
        .reindex(index=np.hstack((df_test.index, df.index.difference(df_test.index))))\
        .fillna('Empty')

print(res)

         bear    dog    cat
green     Yes    Yes     No
yellow    Yes     No     No
red       Yes     No     No
pink    Empty  Empty  Empty

同样的问题。粉色不在字典中,而且这个解决方案会使它消失。 - may
1
@may,不,我没有捏造我的结果... pink 确实出现在最后一行。因此有了 index=np.hstack((df_test.index, df.index.difference(df_test.index))) 这部分代码。 - jpp

2
您可以通过以下方式实现您想要的目标:
# You can use elements that are not in the original dataframe
# and the row will be filled with empty

index_list = ["green", "yellow", "red", "pink", "purple"]

replace_dict = {True: 'Yes', False: 'No', np.nan:'Empty'}

df_test.loc[list(d.keys())].apply(lambda x : pd.Series(x.index.isin(d[x.name]),
        index=x.index), axis=1).reindex(index_list).replace(replace_dict) 

         bear    dog    cat
green     Yes    Yes     No
yellow    Yes     No     No
red       Yes     No     No
pink    Empty  Empty  Empty
purple  Empty  Empty  Empty

解释

您可以通过检查数据框的列是否存在于字典的相应字段中来实现所需的内容:

df_test.loc[list(d.keys())].apply(lambda x : pd.Series(x.index.isin(d[x.name]),
    index=x.index), axis=1)

        bear    dog    cat
green   True   True  False
yellow  True  False  False
red     True  False  False

然后根据字典的键重新索引,以查找缺失的颜色并用空值填充:

index_list = ["green","yellow","red","pink", "purple"]

df_test.loc[list(d.keys())].apply(lambda x : pd.Series(x.index.isin(d[x.name]),
       index=x.index), axis=1).reindex(index_list)

        bear    dog    cat
green   True   True  False
yellow  True  False  False
red     True  False  False
pink     NaN    NaN    NaN
purple   NaN    NaN    NaN

接着,如果你想要改变值,可以使用类似于以下的字典进行替换:

replace_dict = {True: 'Yes', False: 'No', np.nan:'Empty'}

df_test.loc[list(d.keys())].apply(lambda x : pd.Series(x.index.isin(d[x.name]),
        index=x.index), axis=1).reindex(index_list).replace(replace_dict) 

         bear    dog    cat
green     Yes    Yes     No
yellow    Yes     No     No
red       Yes     No     No
pink    Empty  Empty  Empty
purple  Empty  Empty  Empty

@may - 所以你用 index=["green","yellow","red","pink"] 是可以工作的吗? - jezrael
1
是的,它可以!只需将列表放入“reindex”中。如果不存在,它将被填充为“Empty”。添加了一个示例。 - Mabel Villalba

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接