【问题标题】:Repeat dataframe rows n times according to the unique column values and to each row repeat create a new column with different values根据唯一的列值重复数据帧行 n 次,并且对每一行重复创建具有不同值的新列
【发布时间】:2019-02-10 18:59:16
【问题描述】:

正如标题所指出的,我正在尝试获取一个重复行的数据框。 决定 N 次重复执行的因素基于原始数据帧中存在的特定列的唯一值的长度。 执行重复过程后,我想创建一个新列,将原始数据框特定列的所有相同唯一值应用于创建的每个新行。

我知道这有点令人困惑,但我无法尝试以更好的方式揭露我的疑问。因此,为了便于您理解我想要的方法,我们简要介绍了我的数据框和所需的输出数据框:

 >> Original Dataframe

       Samp     Age     Cs
 1       A      51      msi
 2       B      62      cin
 3       C      55      msi
 4       D      70      ebv
 5       E      56      gs
 ....

如您所见,我的 Cs 列有 4 个唯一值(对于不同的数据框可能并不总是相同)。所以,我的目标是获得具有以下结构的数据框:

 >> Desired Dataframe

       Samp     Age     Cs
 1       A      51      msi
 1       A      51      cin
 1       A      51      ebv
 1       A      51      gs
 2       B      62      cin
 2       B      62      msi
 2       B      62      gs
 2       B      62      ebv
 3       C      55      msi
 3       C      55      cin
 3       C      55      ebv
 3       C      55      gs
 4       D      70      ebv
 4       D      70      cin
 4       D      70      msi
 4       D      70      gs
 5       E      56      gs
 5       E      56      cin
 5       E      56      msi
 5       E      56      ebv
 ....

如您所见,在我想要的数据框中,所有行都重复了 4 次(等于唯一 Cs 列值的数量),Cs除外> 列(将其所有唯一值应用于不同的行)。

【问题讨论】:

标签: python pandas dataframe rows repeat


【解决方案1】:

一种解决方案是将'Cs' 转换为Categorical。然后使用GroupBy + first:

df['Cs'] = df['Cs'].astype('category')

res = df.groupby(['Samp', 'Cs']).first().reset_index()
res['Age'] = res.groupby('Samp')['Age'].transform('first').astype(int)

结果

   Samp   Cs  Age
0     A  cin   51
1     A  ebv   51
2     A   gs   51
3     A  msi   51
4     B  cin   62
5     B  ebv   62
6     B   gs   62
7     B  msi   62
8     C  cin   55
9     C  ebv   55
10    C   gs   55
11    C  msi   55
12    D  cin   70
13    D  ebv   70
14    D   gs   70
15    D  msi   70
16    E  cin   56
17    E  ebv   56
18    E   gs   56
19    E  msi   56

【讨论】:

    【解决方案2】:

    您可以使用pivot 函数和fillna 两种方式来计算结果:

    df.pivot('Cs', 'Samp', 'Age').fillna(method='ffill').fillna(method='bfill').unstack().to_frame('Age').reset_index()
    

    【讨论】:

      【解决方案3】:

      使用 numpy.unique 创建另一个 DataFrame 并执行合并,这将产生两个帧的笛卡尔积。

      s = pd.Series(np.unique(df.Cs.values)).rename('Cs').to_frame()
      
      pd.merge(
          df.iloc[:, :2].assign(key=0),
          s.assign(key=0),
          on='key'
      ).drop('key', 1)
      

         Samp  Age   Cs
      0     A   51  cin
      1     A   51  ebv
      2     A   51   gs
      3     A   51  msi
      4     B   62  cin
      5     B   62  ebv
      6     B   62   gs
      7     B   62  msi
      8     C   55  cin
      9     C   55  ebv
      10    C   55   gs
      11    C   55  msi
      12    D   70  cin
      13    D   70  ebv
      14    D   70   gs
      15    D   70  msi
      16    E   56  cin
      17    E   56  ebv
      18    E   56   gs
      19    E   56  msi
      

      时间

      tmp = pd.DataFrame({
          'Samp': np.arange(10000),
          'Age': np.arange(10000),
          'Cs': np.repeat(df.Cs, 2000)
      })
      
      In [90]: %%timeit
          ...: s = pd.Series(np.unique(tmp.Cs.values)).rename('Cs').to_frame()
          ...: pd.merge(
          ...:     tmp.iloc[:, :2].assign(key=0),
          ...:     s.assign(key=0),
          ...:     on='key'
          ...: ).drop('key', 1)
          ...:
      10.3 ms ± 92.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
      
      In [91]: %%timeit
          ...: tmp['Cs'] = tmp['Cs'].astype('category')
          ...:
          ...: res = tmp.groupby(['Samp', 'Cs']).first().reset_index()
          ...: res['Age'] = res.groupby('Samp')['Age'].transform('first').astype(int)
          ...:
          ...:
      51.5 ms ± 1.69 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
      

      【讨论】:

        猜你喜欢
        • 2019-12-22
        • 1970-01-01
        • 2019-05-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-17
        • 1970-01-01
        相关资源
        最近更新 更多