【问题标题】:duplicated rows in pandas append inside for loop熊猫中的重复行附加在for循环中
【发布时间】:2021-01-29 04:59:11
【问题描述】:

我在函数中使用 for 循环时遇到问题。我正在计算单词向量列表的余弦距离。对于每个向量,我正在计算余弦距离,然后将其作为新列附加到 pandas 数据帧。问题是有几个模型,所以我将模型 1 中的词向量与其他模型中的词进行比较。

这意味着某些词并非出现在所有模型中。在这种情况下,我对 KeyError 使用异常并允许循环继续进行而不抛出错误。如果发生这种情况,我还要求在 pandas 数据帧中添加一个 0 值。这导致了重复的索引,并且从这里开始前进。代码如下:

from scipy.spatial.distance import cosine
import pandas as pd

def cosines(model1, model2, model3, model4, model5, model6, model7, words):
    df = pd.DataFrame()

    model = [model2, model3, model4, model5, model6, model7]

    for i in model:
        for j in words:
            try:
                cos = 1 - cosine(model1.wv[j], i.wv[j])
                print(f'cosine for model1 vs {i.name:} {1 - cosine(model1[j], i[j])}')
                tempdf = pd.DataFrame([cos], columns=[f'{j}'], index=[f'{i.name}'])
                #print(tempdf)
                df = pd.concat([df, tempdf], axis=0)
            except KeyError:
                print(word not present at {i.name}')
                ke_tempdf = pd.DataFrame([0], columns=[f'{j}'], index=[f'{i.name}'])
                df = pd.concat([df, ke_tempdf], axis=0)
                pass
    return df

但是,该函数对每个 KeyError 有效 - 它不是在一行中添加一个 0,而是创建一个值为 0 的新副本。用两个单词复制数据帧,但最终目标是拥有一个列表很多话。生成的数据框如下所示:

        word1       word2
model1  0.000000    NaN
model1  NaN         0.761573
model2  0.000000    NaN
model2  NaN         0.000000
model3  0.000000    NaN
model3  NaN         0.000000
model4  0.245140    NaN
model4  NaN         0.680306
model5  0.090268    NaN
model5  NaN         0.662234
model6  0.000000    NaN
model6  NaN         0.709828

正如您所看到的,对于每个不存在的单词,不是将 0 添加到现有模型行 (NaN),而是添加一个编号为 0 的新行。它应该是:model1, 0, 0.76 等,而不是重复的行。非常感谢任何帮助,谢谢!

【问题讨论】:

    标签: python pandas dataframe append


    【解决方案1】:

    如果没有您的模型对象,我无法完全测试它,但我认为这会解决您的问题:

    from scipy.spatial.distance import cosine
    import pandas as pd
    
    def cosines(model1, model2, model3, model4, model5, model6, model7, words):
        df = pd.DataFrame()
    
        model = [model2, model3, model4, model5, model6, model7]
    
        for i in model:
            cos_dict = {}
            for j in words:
                try:
                    cos_dict[j] = 1 - cosine(model1.wv[j], i.wv[j])
                    print(f'cosine for model1 vs {i.name:} {1 - cosine(model1[j], i[j])}')
                except KeyError:
                    print(f'word not present at {i.name}')
                    cos_dict[j] = 0
                    
            tempdf = pd.DataFrame.from_dict(cos_dict, orient='columns')
            tempdf.index = [f'{i.name}']
            
            df = pd.concat([df, tempdf])
                
        return df
    

    它在内部循环的字典中收集每个模型的单词值,并且只在外部循环中将它们添加到完整的数据帧中一次。

    【讨论】:

    • 这很好用 - 谢谢!仅供参考,必须使用标量值指定索引,因此在 tempdf = pd.DataFrame_from_dict 会引发错误 - 我使用以下方法更正了此问题: tempdf = pd.DataFrame([cos_dict]) tempdf.index = [f'{i.name}' ] df = pd.concat([df, tempdf]) 其余部分按预期工作 - 再次感谢!
    • 对于任何感兴趣的人,我使用了另一个肮脏的解决方法,即使用 df.concat([df,tempdf], axis=1) -index 是正确的,但列会根据它来的模型而重复从...然后我折叠重复的列如下: df = df.groupby(df.columns,axis=1).max().fillna(0) - 这也有效!以防有人想要像我这样的垃圾替代品!
    • 确实,您对索引和数据都需要列表是正确的。在我的测试代码中,我实际上做对了,但在转录时错过了它。 :)
    猜你喜欢
    • 2015-10-18
    • 2022-07-18
    • 2017-02-13
    • 2021-12-18
    • 2021-10-26
    • 2019-07-26
    • 2013-10-03
    • 1970-01-01
    相关资源
    最近更新 更多