【问题标题】:create new rows based on values of one of the columns in the above row with specific condition - pandas or numpy根据具有特定条件的上述行中的一列的值创建新行 - pandas 或 numpy
【发布时间】:2020-08-13 05:45:01
【问题描述】:

我有一个如下图所示的数据框

B_ID   no_show  Session  slot_num  walkin   ns_w   c_ns_w     c_walkin
    1     0.4       S1        1       0.2    0.2    0.2       0.2
    2     0.3       S1        2       0.5   -0.2    0.2       0.7 
    3     0.8       S1        3       0.5    0.3    0.5       1.2  
    4     0.3       S1        4       0.8   -0.5    0.0       2.0
    5     0.6       S1        5       0.4    0.2    0.2       2.4 
    6     0.8       S1        6       0.2    0.6    0.8       2.6 
    7     0.9       S1        7       0.1    0.8    1.4       2.7
    8     0.4       S1        8       0.5   -0.1    1.3       3.2
    9     0.6       S1        9       0.1    0.5    1.8       3.3
    12    0.9       S2        1       0.9    0.0    0.0       0.9
    13    0.5       S2        2       0.4    0.1    0.1       1.3  
    14    0.3       S2        3       0.1    0.2    0.3       1.4    
    15    0.7       S2        4       0.4    0.3    0.6       1.8  
    20    0.7       S2        5       0.1    0.6    1.2       1.9
    16    0.6       S2        6       0.3    0.3    1.5       2.2
    17    0.8       S2        7       0.5    0.3    1.8       2.7
    19    0.3       S2        8       0.8   -0.5    1.3       3.5

在哪里,

df[ns_w] = df['no_show'] - df['walkin']

c_ns_w = cumulaitve of ns_w

df['c_ns_w'] = df.groupby(['Session'])['ns_w'].cumsum()

c_walkin = cumulative of walkin

df['c_walkin'] = df.groupby(['Session'])['walkin'].cumsum()

从上面我想计算两个名为u_ns_wu_c_walkin的列。

u_c_walkin > 0.9 使用no_show = 0walkin=0 创建一个新行时,所有其他值将与上述行相同。其中B_ID = walkin1, 2, etc, 并从上面的u_c_walkin 中减去1

同时u_c_ns_w > 0.8 添加一个带有B_ID = overbook1, 2 etc 的新行,带有no_show = 0.5, walkin=0, ns_w = 0.5 和所有其他值与上面的行相同,并从上面的u_c_ns_w 中减去0.5

预期输出:

B_ID   no_show  Session  slot_num  walkin   ns_w   c_ns_w  c_walkin  u_c_walkin  u_c_ns_w
    1     0.4       S1        1       0.2    0.2    0.2    0.2       0.2          0.2
    2     0.3       S1        2       0.5   -0.2    0.2    0.7       0.7          0.2
    3     0.8       S1        3       0.5    0.3    0.5    1.2       1.2          0.5
walkin1   0.0       S1        3       0.0    0.3    0.5    1.2       0.2          0.5
    4     0.3       S1        4       0.8   -0.5    0.0    2.0       1.0          0.0
walkin2   0.0       S1        4       0.0   -0.5    0.0    2.0       0.0          0.0
    5     0.6       S1        5       0.4    0.2    0.2    2.4       0.4          0.2
    6     0.8       S1        6       0.2    0.6    0.8    2.6       0.6          0.8
    7     0.9       S1        7       0.1    0.8    1.4    2.7       0.7          1.4
overbook1 0.5       S1        7       0.0    0.5    1.4    2.7       0.7          0.9
    8     0.4       S1        8       0.5   -0.1    1.3    3.2       1.2          0.8
walkin3   0.0       S1        8       0.0   -0.1    1.3    3.2       0.2          0.8
    9     0.6       S1        9       0.1    0.5    1.8    3.3       0.1          1.3
overbook2 0.5       S1        9       0.0    0.5    1.8    3.3       0.1          0.8
    12    0.9       S2        1       0.9    0.0    0.0    0.9       0.9          0.0     
    13    0.5       S2        2       0.4    0.1    0.1    1.3       1.3          0.1
walkin1   0.0       S2        2       0.0    0.1    0.1    1.3       0.3          0.1
    14    0.3       S2        3       0.1    0.2    0.3    1.4       0.4          0.3
    15    0.7       S2        4       0.4    0.3    0.6    1.8       0.8          0.6
    20    0.7       S2        5       0.1    0.6    1.2    1.9       0.9          1.2
overbook1 0.5       S2        5       0.0    0.5    1.2    1.9       0.9          0.7
    16    0.6       S2        6       0.3    0.3    1.5    2.2       1.2          1.0
walkin2   0.0       S2        6       0.3    0.3    1.5    2.2       0.2          1.0
overbook2 0.5       S2        6       0.0    0.5    1.5    2.2       0.2          0.5
    17    0.8       S2        7       0.5    0.3    1.8    2.7       0.7          0.8
    19    0.3       S2        8       0.8   -0.5    1.3    3.5       1.5          0.3
walkin3   0.0       S2        8       0.8   -0.5    1.3    3.5       0.5          0.3

我尝试下面的代码来创建walkin 行,但无法为overbook 行创建。

def create_u_columns (ser):
    l_index = []
    arr_ns = ser.to_numpy()
    # array for latter insert
    arr_idx = np.zeros(len(ser), dtype=int)
    walkin_id = 1
    for i in range(len(arr_ns)-1):
        if arr_ns[i]>0.8:
            # remove 1 to u_no_show
            arr_ns[i+1:] -= 1
            # increment later idx to add
            arr_idx[i] = walkin_id
            walkin_id +=1
    #return a dataframe with both columns
    return pd.DataFrame({'u_cumulative': arr_ns, 'mask_idx':arr_idx}, index=ser.index)

df[['u_c_walkin', 'mask_idx']]= df.groupby(['Session'])['c_walkin'].apply(create_u_columns)


# select the rows
df_toAdd = df.loc[df['mask_idx'].astype(bool), :].copy()
# replace the values as wanted
df_toAdd['no_show'] = 0
df_toAdd['walkin'] = 0
df_toAdd['EpisodeNumber'] = 'walkin'+df_toAdd['mask_idx'].astype(str)
df_toAdd['u_c_walkin'] -= 1
# add 0.5 to index for later sort
df_toAdd.index += 0.5 

new_df = pd.concat([df,df_toAdd]).sort_index()\
           .reset_index(drop=True).drop('mask_idx', axis=1)

【问题讨论】:

    标签: python pandas numpy pandas-groupby


    【解决方案1】:

    您可以在此处修改此功能以同时进行两项检查。请检查它是否正是您想要申请 walkin 和 overbook 数据帧的条件。

    def create_columns(dfg):
        arr_walkin = dfg['c_walkin'].to_numpy()
        arr_ns = dfg['c_ns_w'].to_numpy()
        # array for latter insert
        arr_idx_walkin = np.zeros(len(arr_walkin), dtype=int)
        arr_idx_ns = np.zeros(len(arr_ns), dtype=int)
        walkin_id = 1
        oberbook_id = 1
        for i in range(len(arr_ns)):
            # condition on c_walkin
            if arr_walkin[i]>0.9:
                # remove 1 to u_no_show
                arr_walkin[i+1:] -= 1
                # increment later idx to add
                arr_idx_walkin[i] = walkin_id
                walkin_id +=1
            # condition on c_ns_w
            if arr_ns[i]>0.8:
                # remove 1 to u_no_show
                arr_ns[i+1:] -= 0.5
                # increment later idx to add
                arr_idx_ns[i] = oberbook_id
                oberbook_id +=1
        #return a dataframe with both columns
        return pd.DataFrame({'u_c_walkin': arr_walkin, 
                             'u_c_ns_w': arr_ns,
                             'mask_idx_walkin':arr_idx_walkin, 
                             'mask_idx_ns': arr_idx_ns }, index=dfg.index)
    
    df[['u_c_walkin', 'u_c_ns_w', 'mask_idx_walkin', 'mask_idx_ns']]=\
       df.groupby(['Session'])[['c_walkin', 'c_ns_w']].apply(create_columns)
    
    
    # select the rows for walkin
    df_walkin = df.loc[df['mask_idx_walkin'].astype(bool), :].copy()
    # replace the values as wanted
    df_walkin['no_show'] = 0
    df_walkin['walkin'] = 0
    df_walkin['B_ID'] = 'walkin'+df_walkin['mask_idx_walkin'].astype(str)
    df_walkin['u_c_walkin'] -= 1
    # add 0.5 to index for later sort
    df_walkin.index += 0.2 
    
    # select the rows for ns_w
    df_ns = df.loc[df['mask_idx_ns'].astype(bool), :].copy()
    # replace the values as wanted
    df_ns['no_show'] = 0.5
    df_ns['walkin'] = 0
    df_ns['ns_w'] = 0.5
    df_ns['B_ID'] = 'overbook'+df_ns['mask_idx_ns'].astype(str)
    df_ns['u_c_ns_w'] -= 0.5
    # add 0.5 to index for later sort
    df_ns.index += 0.4
    
    new_df = pd.concat([df,df_walkin, df_ns]).sort_index()\
               .reset_index(drop=True).drop(['mask_idx_walkin','mask_idx_ns'], axis=1)
    

    你会得到:

    print (new_df)
             B_ID  no_show Session  slot_num  walkin  ns_w  c_ns_w  c_walkin  \
    0           1      0.4      S1         1     0.2   0.2     0.2       0.2   
    1           2      0.3      S1         2     0.5  -0.2     0.2       0.7   
    2           3      0.8      S1         3     0.5   0.3     0.5       1.2   
    3     walkin1      0.0      S1         3     0.0   0.3     0.5       1.2   
    4           4      0.3      S1         4     0.8  -0.5     0.0       2.0   
    5     walkin2      0.0      S1         4     0.0  -0.5     0.0       2.0   
    6           5      0.6      S1         5     0.4   0.2     0.2       2.4   
    7           6      0.8      S1         6     0.2   0.6     0.8       2.6   
    8           7      0.9      S1         7     0.1   0.8     1.4       2.7   
    9   overbook1      0.5      S1         7     0.0   0.5     1.4       2.7   
    10          8      0.4      S1         8     0.5  -0.1     1.3       3.2   
    11    walkin3      0.0      S1         8     0.0  -0.1     1.3       3.2   
    12          9      0.6      S1         9     0.1   0.5     1.8       3.3   
    13  overbook2      0.5      S1         9     0.0   0.5     1.8       3.3   
    14         12      0.9      S2         1     0.9   0.0     0.0       0.9   
    15         13      0.5      S2         2     0.4   0.1     0.1       1.3   
    16    walkin1      0.0      S2         2     0.0   0.1     0.1       1.3   
    17         14      0.3      S2         3     0.1   0.2     0.3       1.4   
    18         15      0.7      S2         4     0.4   0.3     0.6       1.8   
    19         20      0.7      S2         5     0.1   0.6     1.2       1.9   
    20  overbook1      0.5      S2         5     0.0   0.5     1.2       1.9   
    21         16      0.6      S2         6     0.3   0.3     1.5       2.2   
    22    walkin2      0.0      S2         6     0.0   0.3     1.5       2.2   
    23  overbook2      0.5      S2         6     0.0   0.5     1.5       2.2   
    24         17      0.8      S2         7     0.5   0.3     1.8       2.7   
    25         19      0.3      S2         8     0.8  -0.5     1.3       3.5   
    26    walkin3      0.0      S2         8     0.0  -0.5     1.3       3.5   
    
        u_c_walkin  u_c_ns_w  
    0          0.2       0.2  
    1          0.7       0.2  
    2          1.2       0.5  
    3          0.2       0.5  
    4          1.0       0.0  
    5          0.0       0.0  
    6          0.4       0.2  
    7          0.6       0.8  
    8          0.7       1.4  
    9          0.7       0.9  
    10         1.2       0.8  
    11         0.2       0.8  
    12         0.3       1.3  
    13         0.3       0.8  
    14         0.9       0.0  
    15         1.3       0.1  
    16         0.3       0.1  
    17         0.4       0.3  
    18         0.8       0.6  
    19         0.9       1.2  
    20         0.9       0.7  
    21         1.2       1.0  
    22         0.2       1.0  
    23         1.2       0.5  
    24         0.7       0.8  
    25         1.5       0.3  
    26         0.5       0.3 
    

    【讨论】:

    • 嗨,Ben 是否可以遍历列表。这里我们可以更改 (arr_ns[i]>0.8) [0.8, 0.9, 1.0] 并创建 3 个 df,例如 new_df_0.8、new_df_0.9 和 new_df_1.0
    • 请看上面的评论。如果可能,请帮助
    • @Danish 是的,这是可能的,当您创建函数时,您可以添加一个类似 create_columns(dfg, threshold_ns=0.8) 的参数,然后通过 if arr_ns[i]>threshold_ns 更改此函数 if arr_ns[i]>0.8。然后,当您调用应用程序时,您可以使用例如df.groupby(['Session'])[['c_walkin', 'c_ns_w']].apply(lambda x: create_columns(x, 0.9)) 传递此参数。对于其余部分,最好创建一个函数来完成所有其余操作,或者创建一个超过阈值的循环。在这两种情况下,不要忘记创建原始数据框的副本:)
    • @Danish 我现在没有太多时间,但我会稍后再试
    • 在您免费期间请查看以下问题.. 新问题.. 没有人回答.. 与上述问题类似,稍作修改。 stackoverflow.com/questions/62306761/…
    猜你喜欢
    • 2020-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-24
    • 2015-10-18
    相关资源
    最近更新 更多