如何合并两个连续的行并形成一个新列?

时间:2019-05-08 17:24:29

标签: pandas numpy-ndarray

我有一个看起来像这样的DF(从记帐软件中收集)。


    Serial || Date || Particulars || Price
    --------------------------------------
      1    || 0308 || Andrew      || 100
      2    || NaN  || Gloves      || NaN
      3    || 0408 || Johnson     || 50
      4    || NaN  || Wicket      || NaN

我想合并两个连续的行,并使用第二行“特殊”值创建一个新列“产品”。 预期的输出应类似于---

    Serial || Date || Particulars || Price || Product
    -------------------------------------------------
      1    || 0308 || Andrew      || 100   || Gloves
      3    || 0408 || Johnson     || 50    || Wicket

如何用熊猫实现这一目标?

3 个答案:

答案 0 :(得分:4)

这些答案基于数据框的格式,该格式始终显示遵循与OP所提供的相同模式的成对的行。第一行显示一个人,第二行显示产品和日期,价格列为NaN。

依次使用shiftdropna

df.assign(Product=df.Particulars.shift(-1)).dropna()

   Serial   Date Particulars  Price Product
0       1  308.0      Andrew  100.0  Gloves
2       3  408.0     Johnson   50.0  Wicket

join

完全相同但又不同

df.join(df.Particulars.shift(-1).rename('Product')).dropna()

详细信息

每个请求

  • df.Particulars.shift(-1)将“详细信息”列的所有成员都移回一行

    0     Gloves
    1    Johnson
    2     Wicket
    3        NaN
    Name: Particulars, dtype: object
    
  • 当我将其分配给现有数据框df.assign(Product=df.Particulars.shift(-1))时,它将添加一个新名称'Product'的列,其中的值是移位的细节。

       Serial   Date Particulars  Price  Product
    0       1  308.0      Andrew  100.0   Gloves
    1       2    NaN      Gloves    NaN  Johnson
    2       3  408.0     Johnson   50.0   Wicket
    3       4    NaN      Wicket    NaN      NaN
    
  • 剩下的就是使用NaN值删除行,我们已经在上面给出了内容。


@QuangHoang's answer启发

如果我每隔一行进行切片,则无需依赖dropna

df.assign(Product=df.Particulars.shift(-1))[::2]

或更简洁

df[::2].assign(Product=[*df.Particulars[1::2]])

一种实现方式

这是我想到的第一个方法,这很重要

i = np.flatnonzero(df.Price.notna())
j = i + 1

df.iloc[i].assign(Product=df.iloc[j].Particulars.values)

   Serial   Date Particulars  Price Product
0       1  308.0      Andrew  100.0  Gloves
2       3  408.0     Johnson   50.0  Wicket

答案 1 :(得分:1)

丑陋但简单:

ans = df[~pd.isna(df.Date)].copy()
ans['product'] = df[pd.isna(df.Date)].Particulars.values

输出

        Date  Particulars  Price  product
Serial                                  
1       308.0      Andrew  100.0  Gloves
3       408.0     Johnson   50.0  Wicket

答案 2 :(得分:1)

尝试shift并删除偶数行:

df['Product'] = df['Particulars'].shift(-1)
df = df.loc[0:len(df):2]