首页 > 解决方案 > 使用 groupby 构造数据框

问题描述

我的数据框如下所示:

                date    id     pct_change
12355258    2010-07-28  60059   0.210210
12355265    2010-07-28  60060   0.592000
12355282    2010-07-29  60059   0.300273
12355307    2010-07-29  60060   0.481982
12355330    2010-07-28  60076   0.400729

我想用'target','source','weights'列来写它,其中:'target'和'source'都是'id','weights'计算'target'和“来源”同时改变价格。所以它看起来像:

target  source  weights
60059   60060   2
60059   60076   1   
60060   60076   1

我的目标是使用这个数据框来制作一个 networkx 图。

我试过使用 groupby

df.groupby(['date','id'])['id'].unique().value_counts()
df.groupby(['date','id'])['id'].count()

和 for 循环(这很糟糕)。

我觉得我在 groupby 中错过了一小步,但不知道错过了什么。

谢谢您的帮助。

标签: pythonpandasdataframegraphnetworkx

解决方案


pivto_table这个想法是如果 id 对每个日期都有一个 pct_change ,则使用first 来获得 True

#first pivot to get True if any value of id for a date
df_ = df.pivot_table(index='id', columns='date', values='pct_change', 
                     aggfunc=any, fill_value=False)
print(df_)
date  2010-07-28 2010-07-29
id                         
60059       True       True
60060       True       True
60076       True      False

然后,您可以使用combinationfromitertools创建所有可能的对,使用它们选择行并使用&运算符查看两者在同一日期的 True 位置,沿列求和(获取权重列)。将此列分配给从两个组合列表创建的数据框。

# get all combinations of ids
from itertools import combinations
a, b = map(list, zip(*combinations(df_.index, 2)))

res = (pd.DataFrame({'target':a, 'source':b})
         .assign(weigths=(df_.loc[a].to_numpy()
                          &df_.loc[b].to_numpy()
                         ).sum(axis=1))
      )
print(res)
   target  source  weigths
0   60059   60060        2
1   60059   60076        1
2   60060   60076        1

注意:不要忘记用你的分类列的名称来更改index='id'pivot_table否则你的计算机很有可能无法处理以下操作而崩溃


推荐阅读