使用 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


我想用“目标”、“来源”、“权重”列来编写它,其中:“目标”和“来源”都是“id”,“权重”计算“目标”和“权重”的天数“来源”同时改变了价格。所以它看起来像:


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 中少了一小步,但又说不出少了什么。


感谢您的帮助。


莫回无
浏览 136回答 4
4回答

千万里不及你

pivto_table这个想法是如果 id 对每个日期都有 pct_change,则使用first 来获得 True#first pivot to get True if any value of id for a datedf_ = df.pivot_table(index='id', columns='date', values='pct_change',                      aggfunc=any, fill_value=False)print(df_)date  2010-07-28 2010-07-29id                         60059       True       True60060       True       True60076       True      False然后,您可以使用combinationfromitertools创建所有可能的对,使用它们来选择行,并使用&运算符查看在同一日期两者都为 True 的位置,沿列求和(获取权重列)。将此列分配给从两个组合列表创建的数据框。# get all combinations of idsfrom itertools import combinationsa, 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  weigths0   60059   60060        21   60059   60076        12   60060   60076        1注意:不要忘记用您的分类列的名称更改index='id'中的pivot_table,否则您的计算机很可能无法处理以下操作并崩溃

慕莱坞森

尝试这个import pandas as pd, numpy as npids = df.id.unique()WeightDf = pd.DataFrame(index=ids, columns=ids)WeightDf.loc[:, :] = 0def weigh(ID):    IdDates =  set(df.loc[df.id==ID].date.to_list())    for i in ids:        WeightDf.at[ID, i] = len(set.intersection(set(df.loc[df.id==i].date.to_list()), IdDates))        pd.Series(ids).apply(weigh)print(WeightDf)import itertools as ittresult = pd.DataFrame(columns=['Id1', 'Id2', 'Weight'])for i1, i2 in itt.combinations(ids, 2):    result = pd.concat([result, pd.DataFrame(data=[{'Id1':i1, 'Id2':i2,'Weight':WeightDf.loc[i1, i2]}])])print(result)

不负相思意

看到这个用例的很多变化 - 生成组合import itertoolsdf = pd.read_csv(io.StringIO("""                date    id     pct_change12355258    2010-07-28  60059   0.21021012355265    2010-07-28  60060   0.59200012355282    2010-07-29  60059   0.30027312355307    2010-07-29  60060   0.48198212355330    2010-07-28  60076   0.400729"""), sep="\s+")# generate combinations of two... edge case when a group has only one member# tuple of itself to itselfdfx = (df.groupby('date').agg({"id": lambda s: list(itertools.combinations(list(s), 2))                               if len(list(s))>1 else [tuple(list(s)*2)]})    .explode("id")     .groupby("id").agg({"id":"count"})     .rename(columns={"id":"weights"})     .reset_index()     .assign(target=lambda dfa: dfa["id"].apply(lambda s: s[0]),           source=lambda dfa: dfa["id"].apply(lambda s: s[1]))     .drop(columns="id"))print(dfx.to_string(index=False))输出 weights  target  source       2   60059   60060       1   60059   60076       1   60060   60076

MMTTMM

groupby + value_counts。这是代码,以使将来的人们更容易使用:from itertools import combinationsdef combine(batch):    """Combine all products within one batch into pairs"""    return pd.Series(list(combinations(set(batch), 2)))edges = df.groupby('date')['id'].apply(combine).value_counts()c = ['source', 'target']L = edges.index.values.tolist()edges = pd.DataFrame(L, columns=c).join(edges.reset_index(drop=True))
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python