【问题标题】:Is there a faster way to match and multiply Dataframe values based on index values?有没有更快的方法来根据索引值匹配和相乘 Dataframe 值?
【发布时间】:2021-12-31 01:05:38
【问题描述】:

我有两个数据框: 一个(多索引)大小为 (1113, 7897),列中包含不同国家和部门的值,行中包含不同 ID,例如:

F_Frame:

     AT              BE            ...
     Food   Energy   Food   Energy ...
ID1  
ID2
...

在另一个数据框 (CC_LO) 中,我有想要与前一个数据框 (F_frame) 匹配的具有相应国家和 ID 的因子值,所以我如果 F_frame 中的值与国家和 ID 匹配,则将它们与 CC_LO 上的因子值相乘。如果它们不匹配,我会输入一个零。

到目前为止,我的代码似乎可以工作,但运行速度非常慢。有没有更聪明的方法来匹配基于索引/标题名称的表? (代码在 49 个国家/地区循环,并为该国的每 163 个部门乘以相同的因子)

LO_impacts = pd.DataFrame(np.zeros((1113,7987)))

for i in range(0, len(F_frame)): 
    for j in range(0, 49): 
        for k in range(0, len(CF_LO)): 
            if (F_frame.index.get_level_values(1)[i] == CF_LO.iloc[k,1] and 
                F_frame.columns.get_level_values(0)[j*163] == CF_LO.iloc[k,2]): 
                LO_impacts.iloc[i,(j*163):((j+1)*163)] = F_frame.iloc[i,(j*163):((j+1)*163)] * CF_LO.iloc[k,4] 
            else:
                LO_impacts.iloc[i,(j*163):((j+1)*163)] == 0 

【问题讨论】:

  • 让我们看看使用合并的内连接,pandas 确实使用索引(行索引和列标题)自动执行大多数操作。

标签: python pandas dataframe loops match


【解决方案1】:

我已经制作了两个数据帧,然后我为第二个数据帧设置了一个新索引,如下所示:

然后我使用函数 assign() 为 df2 创建了一个新列:

df2=df2.assign(gre_multiply=lambda x: x.gre*df1.gre)

别忘了做df2=,我把它忘在图片里了。

我有以下数据框:

当然它会查看您可以使用计算器检查的索引,它以浮点形式返回值,现在很容易转换为 int 稍后df2.gre_multiply.astype(int) 但在此之前您需要填写na,因为如果两个数据帧的索引不匹配,它将返回 Nan

df2.gre_multiply=df2.gre_multiply.fillna(0).astype(int)

【讨论】:

    【解决方案2】:
    import pandas as pd
    
    # Creating dummy data
    data = pd.DataFrame([
    [2.0, 1.1, 6.7, 4.5],
    [4.3, 5.7, 8.6, 9.0],
    [5.5, 6.8, 9.0, 4.7],
    [5.5, 6.8, 9.0, 4.7],
    ], index = ["S1", "S1", "S2", "S2"], columns = mindex)
    
    mindex = pd.MultiIndex.from_product([["AT", "DK"], ["Food", "Energy"]])
    
    mul_factor = pd.DataFrame({"Country": ['AT', 'DK', 'AT', 'DK'],
              "Value": [1.0, 0.8, 0.9, 0.6],
             }, index = ['S1', 'S1', 'S2', 'S2'])
    
    
    new_data = data.copy()
    new_data.columns = data.columns.to_frame()[0].to_list()
    
    # Reshaping the second Dataframe
    mat = mul_factor.reset_index().pivot(index = 'Country', columns='index')
    mat.index.name = None
    mat = mat.T.reset_index(0, drop = True)
    mat.index.name = None
    
    new_data.multiply(mat) # Required result
    

    如果我误解了您的问题,请告诉我。您可能需要稍微修改代码以适应缺少的国家/地区值。

    【讨论】:

    • 谢谢!这似乎是一个很好的方法,正是我想要的。是否可以在相乘时保持多索引级别,还是必须在两个单索引数据帧之间?
    • 据我所知,它只适用于单索引数据帧
    猜你喜欢
    • 1970-01-01
    • 2019-10-09
    • 2023-02-24
    • 2018-12-12
    • 1970-01-01
    • 2022-12-01
    • 2015-07-17
    • 1970-01-01
    • 2021-08-12
    相关资源
    最近更新 更多