【问题标题】:Subtracting values based on a relationship table根据关系表减去值
【发布时间】:2020-05-14 21:39:06
【问题描述】:

我想开发一些代码,通过使用目标和源的关系表来计算目标位置的值(向下梯度)。一般公式是(值 = 向下梯度 - 向上梯度),或者,给定我的关系表,(值 = 目标 - 所有贡献的源位置)。

在操作上,我想做的与我的另一个posts 类似,只是这次我想使用减法。

那么,让我们开始吧:

import pandas as pd
import networkx as nx
import numpy as np

df = pd.DataFrame({
"Site 1": np.random.rand(10),
"Site 2": np.random.rand(10),
"Site 3": np.random.rand(10),
"Site 4": np.random.rand(10),
"Site 5": np.random.rand(10),
"Site 6": np.random.rand(10)})

和关系表:

df_order = {'source': ["Site 1","Site 2", "Site 3", "Site 4", "Site 5", "Site 6"],
        'target': ["Site 3","Site 3","Site 4","Site 4", "Site 6","None"]
        }
dfo = pd.DataFrame(df_order, columns = ['source', 'target'])

在视觉上,这看起来像:

通过示例计算,我可以通过以下方式在“站点 3”上手动执行操作:

df_sum = df.loc[:,'Site 1':'Site 2'].sum(axis = 1)
df_3_sub = df.loc[:, 'Site 3'].subtract(df_sum)
print(df_3_sub)

在我链接的示例中,我最终得到了一个很好的解决方案(感谢受访者!),我使用了:

import networkx as nx
G = nx.from_pandas_edgelist(df_order.dropna(), 
                            source='source', target='target', 
                            create_using=nx.DiGraph)
nx.draw(G, with_labels=True)

    def all_preds(G, target):
        preds=[target]
        for p in list(G.predecessors(target)):
            preds += all_preds(G, p)
        return preds

pd.concat([
    df[all_preds(G, target)].sum(1).rename(target)
    for target in df_order['source'].unique()
    ], axis=1)

现在,我希望能够从本质上调用 .diff(1) 而不是 sum(1)。有没有相对简单的方法来完成这个?

此外,最上梯度的点(或起点)不会有任何贡献的值,并且不需要将它们转移到新的 DataFrame 中。此外,减法操作将始终从原始 DataFrame 中提取以减去值并将新减去的值放入新的 DataFrame 中。为了清楚起见,例如,我不会将新减去的值放回原始 Dataframe 中以代替原始“Site 3”值。

编辑:

它不是超级漂亮或高效,但我想我知道如何使用 for 循环来解决这个问题:

result= pd.DataFrame()

for site in df2.columns:
    upgradient = df2[all_preds(G, site)].drop(site,axis=1).sum(axis=1)
    downgradient = df2[site]
    calc = downgradient.subtract(upgradient) 
    result.append(calc, ignore_index=True)

我想我只需要在 for 循环的最后一部分获得帮助,以便结果是一个有凝聚力的 DataFrame,并且列名在 for 循环的每一步都与 df2[site] 中的名称相匹配。欢迎对我的代码提出任何想法、cmets 或修改!

【问题讨论】:

    标签: python pandas dataframe math networkx


    【解决方案1】:

    嗯,我想我找到了一种方法来完成我想做的事情。我确信有一种更有效的方法,但这似乎对我有用。如果有更优雅/高效的解决方案,我仍然愿意接受建议。

    import pandas as pd
    import networkx as nx
    import numpy as np  
    
    
    df2 = pd.DataFrame({
        "Site 1": np.random.rand(10),
        "Site 2": np.random.rand(10),
        "Site 3": np.random.rand(10),
        "Site 4": np.random.rand(10),
        "Site 5": np.random.rand(10),
        "Site 6": np.random.rand(10)})
    
    print(df2)
    df_order2 = {'source': ["Site 1","Site 2", "Site 3", "Site 4", "Site 5", "Site 6"],
            'target': ["Site 3","Site 3","Site 5","Site 5", "Site 6","None"]
            }
    
    dfo2 = pd.DataFrame(df_order, columns = ['source', 'target'])
    (print(dfo2))
    
    def all_preds(G, target):
        preds = [target]
        for p in list(G.predecessors(target)):
            preds += all_preds(G, p)
        return preds
    
    result = []
    
    for site in df2.columns:
        upgradient = df2[all_preds(G, site)].drop(site,axis=1).sum(axis=1)
        downgradient = df2[site]
        result.append(downgradient.subtract(upgradient))
    
    rfinal = pd.concat(result, axis=1)  
    rfinal.columns = df2.columns.values
    

    【讨论】:

      猜你喜欢
      • 2021-11-07
      • 1970-01-01
      • 2020-01-12
      • 2021-01-15
      • 1970-01-01
      • 2012-10-10
      • 2021-12-13
      • 1970-01-01
      • 2018-10-07
      相关资源
      最近更新 更多