【问题标题】:Filter a data-frame and add a new column according to the given condition根据给定条件过滤数据框并添加新列
【发布时间】:2019-09-30 17:19:24
【问题描述】:

我有一个这样的数据框

ID      col1           col2 
1    Abc street       2017-07-27 
1    None             2017-08-17 
1    Def street       2018-07-15 
1    None             2018-08-13 
2    fbg street       2018-01-07 
2    None             2018-08-12 
2    trf street       2019-01-15 

我想过滤掉 col1 中的所有 'None' 并将相应的 col2 值添加到新列 col3 中。我的输出是这样的

ID      col1           col2              col3 
1    Abc street       2017-07-27     2017-08-17          
1    Def street       2018-07-15     2018-08-13             
2    fbg street       2018-01-07     2018-08-12             
2    trf street       2019-01-15     

谁能帮我实现这个目标。

【问题讨论】:

  • None 还是'None'
  • 哦!!。它实际上是“无”

标签: python python-3.x pandas numpy pandas-groupby


【解决方案1】:

试试:

filters = df['col1'].isna()
s = df.loc[filters, 'col2'].copy()
df = df[~filters]
df['col3'] = s.values

编辑:正如你所说,你想要的过滤器是'None',而不是None,那么:

filters = df['col1'].eq('None')

【讨论】:

  • 也许你需要检查一些边缘情况,我认为ID是分配的关键,如果你只按值分配,ID可能不匹配
  • 同意@WeNYoBen,这对paste 将值作为一列很危险
  • 确实如此。但是给定的ID 列不是唯一值,因此对其进行分配会失败(我认为)。或者我需要做一个 groupby。
【解决方案2】:

使用ffill + pivot_table。这假定 None 遵循正确的值,从您的数据中可以看出。


u = df.assign(col1=df.col1.replace('None'))
g = ['ID', 'col1']
idx = u.groupby(g).cumcount()

(u.assign(idx=idx)
    .pivot_table(index=g, columns='idx', values='col2', aggfunc='first')
    .reset_index())  

idx   ID        col1           0           1
0      1  Abc street  2017-07-27  2017-08-17
1      1  Def street  2018-07-15  2018-08-13
2      2  fbg street  2018-01-07  2018-08-12
3      2  trf street  2019-01-15         NaN

【讨论】:

    【解决方案3】:

    我正在使用cumcountmerge

    df1=df.loc[df.col1.ne('None'),:].copy()
    df2=df.loc[df.col1.eq('None'),:].copy()
    df1['Key']=df1.groupby('ID').cumcount()
    df2['Key']=df2.groupby('ID').cumcount()
    df1.merge(df2.drop('col1',1),on=['ID','Key'],how='left')
    Out[816]: 
       ID       col1      col2_x  Key      col2_y
    0   1  Abcstreet  2017-07-27    0  2017-08-17
    1   1  Defstreet  2018-07-15    1  2018-08-13
    2   2  fbgstreet  2018-01-07    0  2018-08-12
    3   2  trfstreet  2019-01-15    1         NaN
    

    【讨论】:

      【解决方案4】:

      今天的 Over Engineered with Numpy 版本

      虽然 Numpy 不可否认地非常不明显

      i, rows = pd.factorize([*zip(df.ID, df.col1.replace('None'))])
      k, cols = pd.factorize(df.groupby(i).cumcount())
      
      dleft = pd.DataFrame(dict(zip(['ID', 'col1'], zip(*rows))))
      drigt = pd.DataFrame(index=dleft.index, columns=np.arange(len(cols)) + 2).add_prefix('col')
      drigt.values[i, k] = df.col2.values
      
      dleft.join(drigt)
      
         ID        col1        col2        col3
      0   1  Abc street  2017-07-27  2017-08-17
      1   1  Def street  2018-07-15  2018-08-13
      2   2  fbg street  2018-01-07  2018-08-12
      3   2  trf street  2019-01-15         NaN
      

      【讨论】:

        【解决方案5】:

        又一次尝试:

        f=df['col1']=='None'
        c3=df.loc[f].col2.reset_index(drop=True)
        df=df[~f]
        df2=pd.concat([df.reset_index(drop=True),c3], axis=1, ignore_index=True)
        df2.columns=['ID', 'col1', 'col2', 'col3']
        

           ID        col1        col2        col3
        0   1  Abc street  2017-07-27  2017-08-17
        1   1  Def street  2018-07-15  2018-08-13
        2   2  fbg street  2018-01-07  2018-08-12
        3   2  trf street  2019-01-15         NaN
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-07-01
          • 2021-07-21
          • 1970-01-01
          • 1970-01-01
          • 2012-12-21
          • 2022-06-10
          • 1970-01-01
          • 2018-09-15
          相关资源
          最近更新 更多