【发布时间】: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