【问题标题】:Repeat rows in dataframe for n target columns by adding n-1 target columns通过添加 n-1 个目标列,为 n 个目标列重复数据框中的行
【发布时间】:2021-11-19 07:08:51
【问题描述】:

鉴于以下数据框,其中 A、B、C 是原始输入列,X、Y、Z 是目标列,我想通过将 X 和 Y 的新列添加为 Xi 和易如下。

import pandas as pd

df = pd.DataFrame(data={
    'id': ['1'],
    'A' : ['a1'],
    'B' : ['b1'],
    'C' : ['c1'],
    'X' : ['x1'],
    'Y' : ['y1'],
    'Z' : ['z1']
})
---
   id   A   B   C   X   Y   Z
0   1   a1  b1  c1  x1  y1  z1

对于上面这个df,我想用以下数据创建新的df。

df_new = pd.DataFrame(data={
    'id': ['1', '1', '1'],
    'A' : ['a1', 'a1', 'a1'],
    'B' : ['b1', 'b1', 'b1'],
    'C' : ['c1', 'c1', 'c1'],
    'Xi' : ['0', 'x1', 'x1'],
    'Yi' : ['0', '0', 'y1'],
    'X' : ['x1', '0', '0'],
    'Y' : ['0', 'y1', '0'],
    'Z' : ['0', '0', 'z1']
})
---
   id   A   B   C   Xi  Yi  X   Y   Z
0   1   a1  b1  c1  0   0   x1  0   0
1   1   a1  b1  c1  x1  0   0   y1  0
2   1   a1  b1  c1  x1  y1  0   0   z1

【问题讨论】:

    标签: python-3.x pandas dataframe scikit-learn


    【解决方案1】:

    使用 Index.repeatDataFrame.loc 将重复行复制到长度为 3 的组,然后使用 Series.whereSeries.maskSeries.duplicated 设置 0 值:

    df = df.loc[df.index.repeat(3)].copy()
    
    m1 = df.index.duplicated()
    m2 = df.index.duplicated(keep='last')
    
    df['Xi'] = df['X'].where(m1, 0)
    df['Yi'] = df['Y'].mask(m2, 0)
    
    df['X'] = df['X'].mask(m1, 0)
    df['Y'] = df['Y'].where(m1 & m2, 0)
    df['Z'] = df['Z'].mask(m2, 0)
    
    
    cols = df.columns[:4].tolist() + ['Xi','Yi'] + df.columns[4:7].tolist() 
    df = df.reset_index(drop=True).reindex(cols, axis=1)
    print (df)
      id   A   B   C  Xi  Yi   X   Y   Z
    0  1  a1  b1  c1   0   0  x1   0   0
    1  1  a1  b1  c1  x1   0   0  y1   0
    2  1  a1  b1  c1  x1  y1   0   0  z1
    

    【讨论】:

      【解决方案2】:

      您可以使用numpy.triunumpy.diag 生成适当的布尔掩码。剩下的只是简单的 pandas 掩码:

      df2 = df.loc[df.index.repeat(3)].copy()
      
      mask1 = np.tile(np.triu(np.ones((3,2), dtype=bool)), (len(df), 1))
      mask2 = np.tile(~np.diag(np.ones(3, dtype=bool)), (len(df), 1))
      
      df2[['Xi', 'Yi']] = df2[['X', 'Y']].mask(mask1, 0)
      df2[['X', 'Y', 'Z']] = df2[['X', 'Y', 'Z']].mask(mask2, 0)
      
      df2 = df2[['id', 'A', 'B', 'C', 'Xi', 'Yi', 'X', 'Y', 'Z']]
      

      注意。该解决方案适用于任意数量的行。如果您始终只有一行,则可以删除 numpy.tile 部分。

      输出:

        id   A   B   C  Xi  Yi   X   Y   Z
      0  1  a1  b1  c1   0   0  x1   0   0
      0  1  a1  b1  c1  x1   0   0  y1   0
      0  1  a1  b1  c1  x1  y1   0   0  z1
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-10-07
        • 1970-01-01
        • 2019-01-03
        • 2015-08-19
        • 1970-01-01
        • 1970-01-01
        • 2022-07-20
        • 1970-01-01
        相关资源
        最近更新 更多