代码之家  ›  专栏  ›  技术社区  ›  Claudiu Creanga

在熊猫应用方法中,根据条件复制行

  •  2
  • Claudiu Creanga  · 技术社区  · 7 年前

    这是我的df的一个例子:

    pd.DataFrame([["1", "2"], ["1", "2"], ["3", "other_value"]],
                         columns=["a", "b"])
        a   b
    0   1   2
    1   1   2
    2   3   other_value
    

    我想到达这里:

    pd.DataFrame([["1", "2"], ["1", "2"], ["3", "other_value"], ["3", "row_duplicated_with_edits_in_this_column"]],
                         columns=["a", "b"])
        a   b
    0   1   2
    1   1   2
    2   3   other_value
    3   3   row_duplicated_with_edits_in_this_column
    

    规则是使用APPLY方法,执行一些检查(为了使示例简单,我不包括这些检查),但在某些条件下,对于APPLY函数中的某些行,复制该行,对该行进行编辑,并在df中插入这两行。

    比如:

    def f(row):
       if condition:
          row["a"] = 3
       elif condition:
          row["a"] = 4
       elif condition:
          row_duplicated = row.copy()
          row_duplicated["a"] = 5 # I need also this row to be included in the df
    
       return row
    df.apply(f, axis=1)
    

    我不想将重复的行存储在类中的某个位置,并在末尾添加它们。我想在飞行中做到这一点。

    我见过这个 pandas: apply function to DataFrame that can return multiple rows 但我不确定Groupby是否能帮助我。

    谢谢

    3 回复  |  直到 7 年前
        1
  •  1
  •   Claudiu Creanga    7 年前

    这里有一种方法 df.iterrows 在列表理解中。您需要将行附加到循环中,然后进行concat。

    def func(row):
       if row['a'] == "3":
            row2 = row.copy()
            # make edits to row2
            return pd.concat([row, row2], axis=1)
       return row
    
    pd.concat([func(row) for _, row in df.iterrows()], ignore_index=True, axis=1).T
    
       a            b
    0  1            2
    1  1            2
    2  3  other_value
    3  3  other_value
    

    我发现在我的情况下,最好没有 ignore_index=True 因为我后来合并了2个DFS。

        2
  •  1
  •   jpp    7 年前

    你的逻辑看起来基本上是可向量的。由于输出中的行顺序似乎很重要,因此可以增加默认值 RangeIndex 0.5,然后使用 sort_index .

    def row_appends(x):
        newrows = x.loc[x['a'].isin(['3', '4', '5'])].copy()
        newrows.loc[x['a'] == '3', 'b'] = 10  # make conditional edit
        newrows.loc[x['a'] == '4', 'b'] = 20  # make conditional edit
        newrows.index = newrows.index + 0.5
        return newrows
    
    res = pd.concat([df, df.pipe(row_appends)])\
            .sort_index().reset_index(drop=True)
    
    print(res)
    
       a            b
    0  1            2
    1  1            2
    2  3  other_value
    3  3           10
    
        3
  •  0
  •   Ludo Schmidt    7 年前

    我会对它进行矢量化,按类别进行分类:

    df[df_condition_1]["a"] = 3
    df[df_condition_2]["a"] = 4
    
    duplicates = df[df_condition_3] # somehow we store it ?     
    duplicates["a"] = 5 
    
    #then 
    df.join(duplicates, how='outer')
    

    这个解决方案适合您的需要吗?