【问题标题】:How to replace duplicate dataframe column values with certain conditions in python如何在python中用某些条件替换重复的数据框列值
【发布时间】:2021-02-23 14:11:06
【问题描述】:

我有一个形状 (10x401) 的数据框,其中包含具有相同列名和值的重复列。其中一些具有空值,而另一些具有数值。列名称未按排序顺序。下面给出了一个简短的数据框示例:

       ID#,       1,  1,  1,  1,  2,  2,  2,  2,  3,  3,  3,  3,.........,100,  100, 100, 100
   
        1,         ,   ,   ,   ,  3,  3,  3,  3,   ,   ,   ,   ,.........,  0,    0,   0,   0   
        2,        0,  0,  0,  0,   ,   ,   ,   , 10, 10, 10, 10,.........,   ,     ,    ,   
        3,        9,  9,  9,  9,  1,  1,  1,  1,  4,  4,  4,  4,.........,  1,    1,   1,   1
        .
        .
        .
       10,         ,   ,   ,   ,   ,   ,    ,  ,   ,   ,    ,   ,........., 6,    6,   6,   6

通过忽略空值,对于忽略 ID 列的所有 10 行和 400 列,我需要将每个第一次出现的数值(从 0 到 10)替换为 1,并将其余值替换为 -1。生成的数据框将如下所示:

       ID#,       1,  1,  1,  1,  2,  2,  2,  2,  3,  3,  3,  3,.........,100,  100, 100, 100
   
        1,         ,   ,   ,   ,  1, -1, -1, -1,   ,   ,   ,   ,.........,  1,   -1,   -1, -1   
        2,        1, -1, -1, -1,   ,   ,   ,   ,  1, -1, -1, -1,.........,   ,     ,     ,   
        3,        1, -1, -1, -1,  1, -1, -1, -1,  1, -1, -1, -1,.........,  1,   -1,   -1, -1
        .
        .
        .
       10,         ,   ,   ,   ,   ,   ,    ,  ,   ,   ,    ,   ,........., 1,   -1,   -1, -1

我会感谢您在此提供的帮助。

【问题讨论】:

    标签: python pandas list dataframe csv


    【解决方案1】:

    首先,一些示例数据:

    import pandas as pd
    
    from io import StringIO
    
    df_string = '''
    ID;1;1;1;1;2;2;2;2;3;3;3;3
    1;;;;;3;3;3;3;;;;
    2;0;0;0;0;;;;;10;10;10;10
    3;9;9;9;9;1;1;1;1;4;4;4;4
    4;;;;;;;;;6;6;6;6
    '''
    
    df = pd.read_csv(StringIO(df_string), sep = ";", index_col="ID")
    
    # Removing the automatically added .1/.2/... suffixes. You don't need that for your data.
    df.columns = df.columns.str[0]
    
          1    1    1    1    2    2    2    2     3     3     3     3
    ID                                                                
    1   NaN  NaN  NaN  NaN  3.0  3.0  3.0  3.0   NaN   NaN   NaN   NaN
    2   0.0  0.0  0.0  0.0  NaN  NaN  NaN  NaN  10.0  10.0  10.0  10.0
    3   9.0  9.0  9.0  9.0  1.0  1.0  1.0  1.0   4.0   4.0   4.0   4.0
    4   NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN   6.0   6.0   6.0   6.0
    

    我建议转置 DataFrame,因为使用 pandas 的矢量化方法更方便。它们中的大多数可以通过指定axis=1 来“水平”使用。

    df = df.T
    
    ID    1     2    3    4
    1   NaN   0.0  9.0  NaN
    1   NaN   0.0  9.0  NaN
    1   NaN   0.0  9.0  NaN
    1   NaN   0.0  9.0  NaN
    2   3.0   NaN  1.0  NaN
    2   3.0   NaN  1.0  NaN
    2   3.0   NaN  1.0  NaN
    2   3.0   NaN  1.0  NaN
    3   NaN  10.0  4.0  6.0
    3   NaN  10.0  4.0  6.0
    3   NaN  10.0  4.0  6.0
    3   NaN  10.0  4.0  6.0
    

    首先你需要知道所有有值的单元格:

    ValueMask = ~df.isna()
    
    ID      1      2     3      4
    1   False   True  True  False
    1   False   True  True  False
    1   False   True  True  False
    1   False   True  True  False
    2    True  False  True  False
    2    True  False  True  False
    2    True  False  True  False
    2    True  False  True  False
    3   False   True  True   True
    3   False   True  True   True
    3   False   True  True   True
    3   False   True  True   True
    

    其次,你需要知道一个新组的所有起始位置。将整个 DataFrame 向下移动一行并检查不等式会有所帮助。将其与您的 ValueMask 结合起来,即可为您提供起始单元格:

    StartMask = (df.shift() != df) & ValueMask
    
    ID      1      2      3      4
    1   False   True   True  False
    1   False  False  False  False
    1   False  False  False  False
    1   False  False  False  False
    2    True  False   True  False
    2   False  False  False  False
    2   False  False  False  False
    2   False  False  False  False
    3   False   True   True   True
    3   False  False  False  False
    3   False  False  False  False
    3   False  False  False  False
    

    现在您可以将值的所有单元格设置为-1,然后将作为组开始的所有单元格设置为1

    df[ValueMask] = -1
    df[StartMask] = 1
    
    ID    1    2    3    4
    1   NaN  1.0  1.0  NaN
    1   NaN -1.0 -1.0  NaN
    1   NaN -1.0 -1.0  NaN
    1   NaN -1.0 -1.0  NaN
    2   1.0  NaN  1.0  NaN
    2  -1.0  NaN -1.0  NaN
    2  -1.0  NaN -1.0  NaN
    2  -1.0  NaN -1.0  NaN
    3   NaN  1.0  1.0  1.0
    3   NaN -1.0 -1.0 -1.0
    3   NaN -1.0 -1.0 -1.0
    3   NaN -1.0 -1.0 -1.0
    

    现在您可以随时将其转回:

    df = df.T
    
          1    1    1    1    2    2    2    2    3    3    3    3
    ID                                                            
    1   NaN  NaN  NaN  NaN  1.0 -1.0 -1.0 -1.0  NaN  NaN  NaN  NaN
    2   1.0 -1.0 -1.0 -1.0  NaN  NaN  NaN  NaN  1.0 -1.0 -1.0 -1.0
    3   1.0 -1.0 -1.0 -1.0  1.0 -1.0 -1.0 -1.0  1.0 -1.0 -1.0 -1.0
    4   NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  1.0 -1.0 -1.0 -1.0
    

    【讨论】:

      猜你喜欢
      • 2023-03-08
      • 2018-11-13
      • 2017-07-28
      • 1970-01-01
      • 1970-01-01
      • 2019-07-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多