大熊猫:将多行中的一个单元格的值替换为基于其他列的特定行

时间:2020-07-02 15:32:50

标签: python pandas dataframe

我的目标:

     uniqueIdentity    beginTime    progrNumber
0   2018-02-07-6253554  17:40:29    1
1   2018-02-07-6253554  17:40:29    2
2   2018-02-07-6253554  17:40:29    3
3   2018-02-07-6253554  17:40:29    4
4   2018-02-07-6253554  17:40:29    5
5   2018-02-07-5555333  17:48:29    2
6   2018-02-07-5555333  17:48:29    3
7   2018-02-07-5555333  17:48:29    4
8   2018-02-07-2345622  18:40:29    1
9   2018-02-07-2345622  18:40:29    2
10  2018-02-07-2345622  18:40:29    3
11  2018-02-07-2345622  18:40:29    4

现在

我的数据集:

     uniqueIdentity    beginTime    progrNumber
0   2018-02-07-6253554  17:40:29    1
1   2018-02-07-6253554  17:41:15    2
2   2018-02-07-6253554  17:41:55    3
3   2018-02-07-6253554  17:42:54    4
4   2018-02-07-6253554  17:43:29    5
5   2018-02-07-5555333  17:49:15    2
6   2018-02-07-5555333  17:49:55    3
7   2018-02-07-5555333  17:50:54    4
8   2018-02-07-2345622  18:40:29    1
9   2018-02-07-2345622  18:41:15    2
10  2018-02-07-2345622  18:41:55    3
11  2018-02-07-2345622  18:42:54    4

这意味着: 对于具有相同“ uniqueIdentity”的行,应将“ beginTime”替换为具有相同“ uniqueIdentity”且“ progrNumber”为最小值“ progrNumber”的单元格的值。

5 个答案:

答案 0 :(得分:1)

正如您在评论中提到的那样,最低的progrNumber也将是最低的beginTime。这意味着您可以使用beginTimeuniqueIdentity来取groupby中最低的transform

请注意,如果beginTime是字符串类型,则只有在格式一致的情况下才能使用。 (例如“ 09:40:20”而不是“ 9:40:20”)

df['beginTime'] = df.groupby('uniqueIdentity').beginTime.transform('min')

        uniqueIdentity beginTime progrNumber
0   2018-02-07-6253554  17:40:29           1
1   2018-02-07-6253554  17:40:29           2
2   2018-02-07-5555333  17:48:29           3
3   2018-02-07-5555333  17:48:29           4
4   2018-02-07-6253554  17:40:29           3
5   2018-02-07-6253554  17:40:29           4
6   2018-02-07-5555333  17:48:29           1
7   2018-02-07-5555333  17:48:29           2
8   2018-02-07-2345622  18:40:29           1
9   2018-02-07-2345622  18:40:29           3
10  2018-02-07-2345622  18:40:29           4

答案 1 :(得分:0)

这是使用左联接和一些重命名的另一种选择

    # find rows where progrNumber is 1 
    df_prog1=df[df.progrNumber==1]
    # do a left join on the original 
    df=df.merge(df_prog1,on='uniqueIdentity',how='left',suffixes=('','_y'))
    # keep only the beginTime from the right frame 
    df=df[['uniqueIdentity','beginTime_y','progrNumber']]
    # rename columns
    df=df.rename(columns={'beginTime_y':'beginTime'})
    print(df)

结果:

        uniqueIdentity beginTime  progrNumber
0   2018-02-07-6253554  17:40:29            1
1   2018-02-07-6253554  17:40:29            2
2   2018-02-07-6253554  17:40:29            3
3   2018-02-07-6253554  17:40:29            4
4   2018-02-07-5555333  17:48:29            1
5   2018-02-07-5555333  17:48:29            2
6   2018-02-07-5555333  17:48:29            3
7   2018-02-07-5555333  17:48:29            4
8   2018-02-07-2345622  18:40:29            1
9   2018-02-07-2345622  18:40:29            2
10  2018-02-07-2345622  18:40:29            3
11  2018-02-07-2345622  18:40:29            4

如果不确定uniqueIdentity中的哪条记录将具有最短的时间,则可以使用groupby而不是选择progrNumber==1的位置:

    df_prog1=df.groupby('uniqueIdentity')['beginTime'].min().reset_index()

然后像上面那样进行左连接。

答案 2 :(得分:0)

如果每个用户的第一个beginTime将始终与每个用户的最小程序号相对应,则可以执行以下操作:

d = df.groupby('uniqueIdentity')['beginTime'].first().to_dict()
df['beginTime'] = df['uniqueIdentity'].map(d)

要更清楚地获得程序编号最小的时间(与程序位置无关),请在上面将d替换为:

d = df.groupby('uniqueIdentity').apply(lambda x: x['beginTime'][x['progrNumber'].idxmin()]).to_dict()

这两个示例数据的结果相同,但是如果某些用户的第一个beginTime(或每个Hugolmn的最小beginTime)与最小{{1 }}给用户

答案 3 :(得分:0)

使用groupbymap

假设是beginTime对于最小的progrNumber总是最小的。根据问题的评论,此条件为真。

在这个答案中,我收集了每个uniqueIdentity的最小beginTime,然后将其映射到基于uniqueIdentity的原始DataFrame。

times = df.groupby('uniqueIdentity').beginTime.min()
df['beginTime'] = df.uniqueIdentity.map(times)

答案 4 :(得分:0)

如果我们不能假设最小值locals { common_variables_map = { for v in var.common_variables : "${v.workspace_name}/${v.var_name}" => v } custom_variables_map = { for v in var.custom_variables : "${v.workspace_name}/${v.var_name}" => v } common_keys = [ for v in var.common_variables : "${v.workspace_name}/${v.var_name}" ] custom_keys = [ for v in var.common_variables : "${v.workspace_name}/${v.var_name}" ] all_keys = distinct(concat(common_keys, custom_keys)) merged = [ for k in local.all_keys: contains(common_variables_map, k) ? common_variables_map[k] : custom_variables_map[k] ] } 也是最小值terraform apply -var-file="common.tfvars" -var-file="custom.tfvars" ,则需要一种更加复杂的方法:

progrNumber

如果您不希望使用oneliner,则最好使用beginTime的方法

df['beginTime'] = (
     df.groupby('uniqueIdentity', as_index=False, group_keys=False)
       .apply(lambda s: pd.Series(s[s.progrNumber==s.progrNumber.min()]
              .beginTime.item(), index=s.index)
       )
)

df
#    uniqueIdentity beginTime   progrNumber
# 0  2018-02-07-6253554 17:40:29    1
# 1  2018-02-07-6253554 17:40:29    2
# 2  2018-02-07-6253554 17:40:29    3
# 3  2018-02-07-6253554 17:40:29    4
# 4  2018-02-07-6253554 17:40:29    5
# 5  2018-02-07-5555333 17:49:15    2
# 6  2018-02-07-5555333 17:49:15    3
# 7  2018-02-07-5555333 17:49:15    4
# 8  2018-02-07-2345622 18:40:29    1
# 9  2018-02-07-2345622 18:40:29    2
# 10 2018-02-07-2345622 18:40:29    3
# 11 2018-02-07-2345622 18:40:29    4

注意:如果您保证只有一个值的最小值为map,则可以用mapping = ( df.groupby('uniqueIdentity') .apply(lambda s: s[s.progrNumber==s.progrNumber.min()].beginTime.iloc[0]) ) df['beingTime'] = df.uniqueIdentity.map(mapping) 代替iloc[0]