【问题标题】:How to merge multiple pandas column object type values into one column while ignoring "None"?如何在忽略“无”的情况下将多个熊猫列对象类型值合并到一列中?
【发布时间】:2018-09-03 22:10:48
【问题描述】:

起始数据框:

pd.DataFrame({'col1': ['one', 'None', 'None'], 'col2': ['None', 'None', 'six'], 'col3': ['None', 'eight', 'None']})

最终目标:

pd.DataFrame({'col4': ['one', 'eight', 'six']})

我想做什么:

df['col1'].map(str)+df['col2'].map(str)+df['col3'].map(str)

如何在忽略“无”值的情况下将多个 pandas 列对象类型值合并到一列?顺便说一句,在这个数据集中,最终数据框单元格中的值永远不会超过一个。

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    你有字符串Nones,而不是实际的空值,所以你需要先替换它们。

    选项 1
    replace/mask/where + fillna + agg

    df.replace('None', np.nan).fillna('').agg(''.join, axis=1).to_frame('col4')
    

    或者,

    df.mask(df.eq('None')).fillna('').agg(''.join, axis=1).to_frame('col4')
    

    或者,

    df.where(df.ne('None')).fillna('').agg(''.join, axis=1).to_frame('col4')
    

        col4
    0    one
    1  eight
    2    six
    

    选项 2
    replace + pd.notnull

    v = df.replace('None', np.nan).values.ravel()
    pd.DataFrame(v[pd.notnull(v)], columns=['col4'])
    
        col4
    0    one
    1  eight
    2    six
    

    选项 3
    利用 Divakar 出色的justify 功能的解决方案:

    pd.DataFrame(justify(df.values, invalid_val='None')[:, 0], columns=['col4'])
    
        col4
    0    one
    1  eight
    2    six
    

    参考
    (注意,您需要稍微修改函数才能很好地处理字符串数据。)

    def justify(a, invalid_val=0, axis=1, side='left'):    
        """
        Justifies a 2D array
    
        Parameters
        ----------
        A : ndarray
            Input array to be justified
        axis : int
            Axis along which justification is to be made
        side : str
            Direction of justification. It could be 'left', 'right', 'up', 'down'
            It should be 'left' or 'right' for axis=1 and 'up' or 'down' for axis=0.
    
        """
    
        if invalid_val is np.nan:
            mask = ~np.isnan(a)
        else:
            mask = a!=invalid_val
        justified_mask = np.sort(mask,axis=axis)
        if (side=='up') | (side=='left'):
            justified_mask = np.flip(justified_mask,axis=axis)
        out = np.full(a.shape, invalid_val, dtype='<U8')    # change to be made is here
        if axis==1:
            out[justified_mask] = a[mask]
        else:
            out.T[justified_mask.T] = a.T[mask.T]
        return out
    

    【讨论】:

      【解决方案2】:

      另一种方式,为了给你选择:

      pd.DataFrame(df[df!='None'].stack().values, columns=['col4'])
      
          col4
      0    one
      1  eight
      2    six
      

      【讨论】:

      • 这很聪明! :)
      • 是的,我同意,我喜欢这个。 +1
      【解决方案3】:

      或者

      df[df!='None'].fillna('').sum(1)
      Out[1054]: 
      0      one
      1    eight
      2      six
      dtype: object
      

      listmap

      list(map(lambda x : ''.join(x) ,df.replace({'None':''}).values))
      Out[1061]: ['one', 'eight', 'six']
      

      【讨论】:

        【解决方案4】:
        df['col4']=df.apply(lambda x: x.max(),axis=1)
        

        【讨论】:

          猜你喜欢
          • 2021-10-25
          • 2015-09-03
          • 2018-09-29
          • 2017-05-28
          • 1970-01-01
          • 1970-01-01
          • 2022-11-03
          • 1970-01-01
          • 2017-09-14
          相关资源
          最近更新 更多