【问题标题】:pandas fill column with random numbers with a total for each row熊猫用随机数填充列,每行总计
【发布时间】:2019-07-10 21:35:52
【问题描述】:

我有一个这样的熊猫数据框:

     id  foo  
 0   A   col1 
 1   A   col2  
 2   B   col1  
 3   B   col3  
 4   D   col4  
 5   C   col2  

我想根据foo 列中的唯一值创建另外四个列。 col1,col2,col3,col4

     id  foo   col1 col2 col3 col4
 0   A   col1   75   20   5    0
 1   A   col2   20   80   0    0
 2   B   col1   82   10   8    0
 3   B   col3   5    4   80   11
 4   D   col4   0    5   10   85
 5   C   col2   12   78   5    5

创建列的逻辑如下:

如果 foo = col1col1 包含介于 75-100 和其他列(col2col3col4)之间的随机数,这样每个列的总数行是100

我可以手动创建一个新列并分配一个随机数,但我不确定如何为每行 100 包含 sum 的逻辑。

感谢任何帮助!

【问题讨论】:

    标签: python-3.x pandas


    【解决方案1】:

    我的两分钱

    d=[]
    s=np.random.randint(75,100,size=6)
    
    for x in 100-s:
        a=np.random.randint(100, size=3)
        b=np.random.multinomial(x, a /a.sum())
        d.append(b.tolist())
    s=[np.random.choice(x,4,replace= False) for x in np.column_stack((s,np.array(d))) ]
    
    
    df=pd.concat([df,pd.DataFrame(s,index=df.index)],1)
    df
    
      id   foo   0   1   2   3
    0  A  col1  16   1   7  76
    1  A  col2   4   2  91   3
    2  B  col1   4   4   1  91
    3  B  col3  78   8   8   6
    4  D  col4   8  87   3   2
    5  C  col2   2   0  11  87
    

    【讨论】:

      【解决方案2】:

      IIUC,

      df['col1'] = df.apply(lambda x: np.where(x['foo'] == 'col1', np.random.randint(75,100), np.random.randint(0,100)), axis=1)
      
      df['col2'] = df.apply(lambda x: np.random.randint(0,100-x['col1'],1)[0], axis=1)
      
      df['col3'] = df.apply(lambda x: np.random.randint(0,100-x[['col1','col2']].sum(),1)[0], axis=1)
      
      df['col4'] = 100 - df[['col1','col2','col3']].sum(1).astype(int)
      
      df[['col1','col2','col3','col4']].sum(1)
      

      输出:

        id   foo col1  col2  col3  col4
      0  A  col1   92     2     5     1
      1  A  col2   60    30     0    10
      2  B  col1   89     7     3     1
      3  B  col3   72    12     0    16
      4  D  col4   41    52     3     4
      5  C  col2   72     2    22     4
      

      【讨论】:

        【解决方案3】:

        我的方法

        import numpy as np
        
        def weird(lower, upper, k, col, cols):
            first_num = np.random.randint(lower, upper)
            delta = upper - first_num
            the_rest = np.random.rand(k - 1)
            the_rest = the_rest / the_rest.sum() * (delta)
            the_rest = the_rest.astype(int)
            the_rest[-1] = delta - the_rest[:-1].sum()
        
            key = lambda x: x != col
            return dict(zip(sorted(cols, key=key), [first_num, *the_rest]))
        
        
        def f(c): return weird(75, 100, 4, c, ['col1', 'col2', 'col3', 'col4'])
        
        df.join(pd.DataFrame([*map(f, df.foo)]))
        
          id   foo  col1  col2  col3  col4
        0  A  col1    76     2    21     1
        1  A  col2    11    76    11     2
        2  B  col1    75     4    10    11
        3  B  col3     0     1    97     2
        4  D  col4     5     4    13    78
        5  C  col2     9    77     6     8
        

        【讨论】:

          【解决方案4】:

          如果我们将75-100 之间的数字减去75,问题就变成了在0-25 之间生成一个随机数表,其每行总和为25。可以通过逆向解决cumsum

          num_cols = 4
          
          # generate random number and sort them in each row
          a = np.sort(np.random.randint(0,25, (len(df), num_cols)), axis=1)
          
          # create a dataframe and attach a last column with values 25
          new_df = pd.DataFrame(a)
          new_df[num_cols] = 25
          
          # compute the difference, which are our numbers and add to the dummies:
          dummies = pd.get_dummies(df.foo) * 75
          dummies += new_df.diff(axis=1).fillna(new_df[0]).values
          

          假人是

             col1  col2  col3  col4
          0  76.0  13.0   2.0   9.0
          1   1.0  79.0   2.0   4.0
          2  76.0   5.0   8.0   9.0
          3   1.0   3.0  79.0  10.0
          4   1.0   2.0   1.0  88.0
          5   1.0  82.0   1.0   7.0
          

          可以连接到原始数据帧。

          【讨论】:

            猜你喜欢
            • 2018-05-07
            • 2021-03-18
            • 1970-01-01
            • 2021-10-04
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-05-13
            相关资源
            最近更新 更多