代码之家  ›  专栏  ›  技术社区  ›  Frank AK

如何基于其他列向dataframe添加新行?

  •  2
  • Frank AK  · 技术社区  · 7 年前

    比方说,我有下面的数据框作为示例。

        name  age  status  price
    0  frank   12       1    100
    1   jack   33       0    190
    2    joe   22       1    200
    ******************************
    

    期望输出:

        name  age  status  price
    0  frank   12       1    100
    1   jack   33       0    190
    2   jack   NaN      0    -190
    3    joe   22       1    200
    ******************************
    

    我还在下面发布了示例数据框,因此您可以轻松地对其进行测试。

    df1 = pd.DataFrame({
            "name":["frank", "jack", "joe"],
            "age": [12, 33, 22],
            "status": [1,0, 1],
            "price": [100,190, 200]
    })
    

    如您所见,我想在上面这一行的基础上插入一个新行 status 为0,表示事务失败。为了更方便地进行统计,我想在该行下面生成一个新行。我也想要它 price 是负数。因为我不关心新行的整个列,所以我希望另一列是 NaN ,就像我想要的输出中的“年龄”。

    到目前为止我都试过了。

    import pandas as pd
    import numpy as np
    
    df1 = pd.DataFrame({
            "name":["frank", "jack", "joe"],
            "age": [12, 33, 22],
            "status": [1,0, 1],
            "price": [100,190, 200]
    })
    
    df2_list = []
    
    for i, row in df1.iterrows():
        if row["status"] == 0:
            origin_row = row.to_dict()
            new_row = ({
                    "name": origin_row.get("name"),
                    #"age": origin_row.get("age"),
                    "age": np.NaN,
                    "status": origin_row.get("status"),
                    "price": -origin_row.get("price"),
    
                })
            df2_list.append(new_row)
    df2 = pd.DataFrame(df2_list)
    # concat df1 and df2 and sort it .
    df3 = pd.concat([df1, df2], ignore_index=True)
    df4 = df3.sort_values(['name', 'price'], ascending=[True, False])
    print(df4)
    

    我有一个循环,检查它是否符合我的条件 status==0 ,并将其附加到我的tmp列表中,而且…但是代码太多了。我想知道有没有什么好办法,我是说更多的Pythonic代码或者pandas已经有了一些功能可以吗?

    1 回复  |  直到 7 年前
        1
  •  3
  •   cs95 abhishek58g    7 年前

    使用 numpy.repeat 添加行,以及 Series.duplicated 定价。

    df2 = pd.DataFrame(df.values.repeat(df.status.eq(0)+1, axis=0), columns=df.columns)
    df2.loc[df2.name.duplicated(), 'price'] *= -1
    df2
    
        name age status price
    0  frank  12      1   100
    1   jack  33      0   190
    2   jack  33      0  -190
    3    joe  22      1   200
    

    如果您还需要在“年龄”列中屏蔽NaN,可以使用 Series.mask .

    df2.age.mask(df2.name.duplicated())
    
    0     12
    1     33
    2    NaN
    3     22
    Name: age, dtype: object
    

    完整代码。

    df2 = pd.DataFrame(df.values.repeat(df.status.eq(0)+1, axis=0), columns=df.columns)
    isdup = df2.name.duplicated()
    df2.loc[isdup, 'price'] *= -1
    df2['age'] = df2['age'].mask(isdup)
    
    df2
        name  age status price
    0  frank   12      1   100
    1   jack   33      0   190
    2   jack  NaN      0  -190
    3    joe   22      1   200