代码之家  ›  专栏  ›  技术社区  ›  Phil

熊猫在Groupby之后合并行

  •  0
  • Phil  · 技术社区  · 7 年前

    id ,而且我知道ID将在dataframe中正好存在一行(“不匹配”)或两行(“matched”)。

    • 为了选择不匹配的行和匹配的行对,我可以使用 groupby 在ID列上。
    • 现在,对于每个组,我想从第二行(对)中提取一些列,重命名它们,并将它们复制到第一行。然后我可以丢弃所有第二行,并返回一个包含所有修改过的第一行的数据帧(对于每个组)。

    id=1 和 3 id=2

    entity id partner value
    A      1  B       200
    B      1  A       300
    A      2  B       600
    B      3  C       350
    C      3  B       200
    

    由此产生的转变应该留给我以下几点:

    entity id partner entity_value partner_value
    A      1  B       200          300
    A      2  B       600          NaN
    B      3  C       350          200
    

    让我困惑的是如何找到一种通用的匹配方法 partner_value

    0 回复  |  直到 7 年前
        1
  •  3
  •   smci    7 年前

    dfg = df.groupby('id', sort=False)
    
    # Create 'entity','id','partner','entity_value' from the first row...
    df2 = dfg['entity','id','partner','value'].first().rename(columns={'value': 'entity_value'})
    
    # Now insert 'partner_value' from those groups that have a second row...
    df2['partner_value'] = nan
    df2['partner_value'] = dfg['value'].nth(n=1)
    
       entity  id partner  entity_value  partner_value
    id                                                
    1       A   1       B           200          300.0
    2       A   2       B           600            NaN
    3       B   3       C           350          200.0
    

    pd.groupby(...).agg(...) 原则上允许您指定 (column, aggregate_function) could then chain those into a rename ,这在这里不起作用,因为我们要在 value pandas.core.base.SpecificationError: Function names must be unique, found multiple named value ).

    其他并发症:

    • 我们不能 使用 groupby.nth(n) 乍一看,这听起来很有用,除了它只在数据帧上,而不是像 df['value'] ,它也会悄悄地删除没有第n个元素的组,而不是我们想要的。(但它确实保留了索引,所以我们可以使用它,首先将列初始化为all nan,然后有选择地在该列上插入,如上所述)。
    • pd.groupby.agg() 语法甚至不让你打电话 nth() 只需将'nth'作为agg_ncname传递,因为 第N() 缺少它的 n 你必须声明一个lambda。
    • 我试着定义以下函数 second_else_nan agg() 如上所述,但是经过了很多的努力,我还是不能让它运行起来,原因有很多,只有一个原因是你不能在同一列上做两个agg:

    代码:

    def second_else_nan(v):
        if v.size == 2:
            return v[1]
        else:
            return pd.np.nan
    

    (即 dict.get(key, default)

        2
  •  1
  •   Nakor    7 年前

    我会这么做的。首先,得到第一个值:

    df_grouped = df.reset_index().groupby('id').agg("first")
    

    df_grouped["partner_value"] = df.groupby("id")["value"].agg("last")
    

    唯一的问题是您有一个重复的值,以防它不被复制(而不是一个NaN)。

        3
  •  0
  •   AndrewH    7 年前

    grouped = df.groupby("id")
    first_values = grouped.agg("first")
    sums = grouped.agg("sum")
    first_values["partner_value"] = sums["value"] - first_values["value"]
    first_values["partner_value"].replace(0, np.nan, inplace=True)
    
    transformed_df = first_values.copy()
    

    按id对数据分组,取第一行,取每组“value”列的总和,从中减去第一行的“value”。然后将结果列中的0替换为np.nan公司(此处假设“value”列中的数据从不为0)