【问题标题】:Merge DataFrames in Pandas using arbitrary weights使用任意权重合并 Pandas 中的 DataFrame
【发布时间】:2021-07-04 18:20:44
【问题描述】:

这个问题非常类似于:Merge DataFrames in Pandas using the mean,但我需要使用任意权重,而不仅仅是简单的平均值。

我有两个看起来像这样的 DF:

df1

from_code to_code frequency
a a 0.2
a b 0.4

df2

from_code to_code frequency
a a 0.3
a b 0.5
a c 0.7

列是相同的。 from_code 和 to_code 中的值不一定相同。有很多重叠,但 df1 中的 from_code 和 to_code 中可能有一些 df2 中不存在的值。

我还有权重 w1 和 w2 的总和为 1。假设 w1 = 0.1 和 w2 = 0.9

我想要合并两个数据框以获得一个看起来像这样的新数据框:

from_code to_code frequency
a a 0.29
a b 0.49
a c 0.63

请注意,新表中的频率为 w1 *(来自 df1 的频率)+ w2 *(来自 df2 的频率)。如果 df1 或 df2 中缺少一行,则应将频率视为零。

请注意,如果我有 w1 = w2 = 0.5,那么我只是取平均值。我可以按如下方式解决这种特殊情况:

merged_df = pd.concat((df1, df2))
final_df = merged_df.groupby(['from_code', 'to_code']).mean().reset_index()

一般来说,我可能有超过 2 个 dfs,一般在 2 到 4 之间,但数量将是一个变量。我想如果我能得到帮助解决 2 dfs 的情况,我可以概括为 n dfs,但如果有人想走得更远,给我一个通用的解决方案,那就太酷了。

当我等待一个很棒的答案时,我将尝试创建一个如下所示的中间表:

from_code_1 to_code_1 freq_1 w_1 from_code_2 to_code_2 freq_2 w_2 new_freq
a a 0.2 0.1 a a 0.3 0.9 [calc]
a b 0.4 0.1 a b 0.5 0.9 [calc]
a c 0.0 0.1 a c 0.7 0.9 [calc]

我将尝试通过创建该表、填充 new_freq,然后将表缩减为仅三列(from_code、to_code、new_freq)来拼凑我的方式,但我希望有一种更优雅的方式来使用 Pandas 合并或其他方式执行此操作。

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    您可以将权重应用于每个 DataFrame 的 frequency,然后像您一样将 concatgroupby 应用于(但取总和而不是平均值):

    df1 = pd.DataFrame({'from_code': ['a','a'],
                        'to_code':['a','b'],
                        'frequency':[0.2, 0.4]})
    
    df2 = pd.DataFrame({'from_code': ['a','a', 'a'],
                        'to_code':['a','b','c'],
                        'frequency':[0.3, 0.5, 0.7]})
    
    # weight the values
    df1['frequency'] *= 0.1
    df2['frequency'] *= 0.9
    
    # aggregate
    output = pd.concat([df1, df2]).groupby(['from_code', 'to_code']).sum().reset_index()
    

    结果output

      from_code to_code  frequency
    0         a       a       0.29
    1         a       b       0.49
    2         a       c       0.63
    

    一般的公式是有一个 DataFrame 列表和一个权重列表,循环应用权重然后聚合。

    我不确定您的描述是否是这种情况,但假设在每个 DataFrame 中,行相对于 from_codeto_code 是唯一的(如您的例子)。如果不是,则必须在每个 DataFrame 上执行额外的groupby 以解决对一个代码的多次观察。

    这也修改了原来的DataFrames;这可以通过在应用权重之前复制数据来避免。

    【讨论】:

    • 完美!非常感谢。 (是的,这些行在 from_code 和 to_code 方面是唯一的。)
    • 所以,事实证明这段代码实际上并没有工作。这是我的确切代码(列名与我在原始帖子中的示例略有不同): # concatenates new_tm = pd.concat(original_trans_mats[prefix_key]) # 添加具有新权重的新列 new_tm['new_weight'] = new_tm[' rel_frequency'] * new_tm['weight'] # 删除旧的 rel_frequency 和权重 cols new_tm = new_tm.drop(['rel_frequency', 'weight'], axis=1) # 按我保留的两列分组,对 new_weight 求和new_tm.groupby(['from_str', 'to_char']).sum().reset_index()
    • 问题是在运行该代码后,我没有有唯一的行。我有 from_str 和 to_char 相同的重复项(但重量不同)。所以它实际上并没有对 from_str 和 to_char 进行 groupby,我不知道为什么。
    • 没关系,我想通了。我需要: new_tm = new_tm = new_tm.groupby(['from_str', 'to_char']).sum().reset_index()
    猜你喜欢
    • 1970-01-01
    • 2018-11-05
    • 2013-10-29
    • 2017-11-27
    • 1970-01-01
    • 1970-01-01
    • 2021-12-12
    • 2018-09-19
    • 2019-11-10
    相关资源
    最近更新 更多