【问题标题】:pandas python Update subset of column A based on subset of one or more other columnspandas python根据一个或多个其他列的子集更新A列的子集
【发布时间】:2019-07-28 19:10:00
【问题描述】:

编辑我已经修改了以下描述的部分内容,以阐明我所说的“功能”和“组”的含义,更正了一个错字,并包含了我尝试过的其他代码。

我的 pandas df 有 450 万行和 23 列。下表显示了来自df2 的几行代码,这些代码是从df 生成的。它显示了两个组(eeskinhduquant)和三个特征(failedexit_statusjob_number ):

# report by group

        group      feature  #_cats #_jobs  rank        top_value  freq  \
10   eeskin    failed       1       6     -1     100              6      
21   eeskin    exit_status  1       6     -1     0                6     
0    eeskin    job_number   1       6     -1     4.08219e+06      6      
21   hduquant  exit_status  5       64    -1     37               58     
11   hduquant  failed       2       64    -1     0                63     
1    hduquant  job_number   2       64    -1     4.07192e+06      61     

-1 的“rank”列值是一个占位符。

我想为每个功能更新每个组的排名。在这种情况下,“特征”是指“特征”列中的每个唯一值:failedexit_statusjob_number。例如,更新 job_number 的排名意味着仅在“feature”列等于 job_number 的行上修改“rank”列中的值。事实证明,这些行中的每一行还对应于“组”列中的不同组值。

因此,我不想一次更新“rank”列中的所有值,而是希望逐个功能地执行它们,每次写入都会更新单个功能上所有组的值。

特征“job_number”的排名基于“#_jobs”col 的值(最高职位数为排名1)。对于“失败”的特征,排名基于“top_value”的“freq”。 exits_status 现在可以保持 -1。

结果应该是这样的:

        group      feature  #_cats #_jobs  rank        top_value  freq  \
10   eeskin    failed       1       6      1     100              6      
21   eeskin    exit_status  1       6     -1     0                6     
0    eeskin    job_number   1       6      2     4.08219e+06      6      
21   hduquant  exit_status  5       64    -1     37               58     
11   hduquant  failed       2       64     2     0                63     
1    hduquant  job_number   2       64     1     4.07192e+06      61     

“eeskin”在failed 中排名第一,在job_number 中排名第二。 “hdquant”在failed 中排名第 2,在job_number 中排名第 1。

我可以使用以下代码更新 job_number 的排名值:

if feat == 'job_number':
     grouped = grouped.sort_values("#_jobs", ascending=False)
     grouped['rank'] = grouped.index + 1
        group      feature  #_cats #_jobs  rank        top_value  freq  \
10   eeskin    failed       1       6     -1     100              6      
21   eeskin    exit_status  1       6     -1     0                6     
0    eeskin    job_number   1       6      2     4.08219e+06      6      
21   hduquant  exit_status  5       64    -1     37               58     
11   hduquant  failed       2       64    -1     0                63     
1    hduquant  job_number   2       64     1     4.07192e+06      61     

但是当我尝试更新两者时,都没有更新:

feat = ['job_number', 'failed']

for f in feat:
    if f == 'job_number':
        grouped = grouped.sort_values("#_jobs", ascending=False)
        grouped['rank'] = grouped.index + 1
    elif f == 'failed':  #  or f == 'exit_status'
        x = len(not grouped[f] == 0)
        grouped['x'] = x
        grouped = grouped.sort_values("x", ascending=False)
        grouped['rank'] = grouped.index + 1      
        del grouped['x']
        group      feature  #_cats #_jobs  rank        top_value  freq  \
10   eeskin    failed       1       6     -1     100              6      
21   eeskin    exit_status  1       6     -1     0                6     
0    eeskin    job_number   1       6     -1     4.08219e+06      6      
21   hduquant  exit_status  5       64    -1     37               58     
11   hduquant  failed       2       64    -1     0                63     
1    hduquant  job_number   2       64    -1     4.07192e+06      61     

我已尝试实施 Matt W. 的建议,但到目前为止没有成功:

df.loc[df.feature == 'job', 'rank'] = df.loc[df.feature == 'job', 'jobs'].rank(ascending=False)

我将他的代码修改如下,但也没有成功:

df2.loc[df2['feature' == 'job_number'] & df2['rank']] = (df2.loc[df2['#_jobs']].rank(ascending=False))

附录 @Matt W.

输入:

import pandas as pd

df = pd.DataFrame([['g1', 'u1', 3902779, '2018-09-27 21:38:06', '2018-10-01 07:24:38', '2018-10-01 08:00:42', 0, 0, 'single', 1, 55696, 609865728.0, 4.0, 6.0, 0, 0, 4.0, 0, 'single', 1, 0, pd.Timedelta('3 days 09:46:32'), pd.Timedelta('00:36:04')]], 
                          columns=['group', 'owner', 'job_number', 'submission_time', 'start_time', 'end_time', 'failed', 'exit_status', 'granted_pe', 'slots', 'task_number', 'maxvmem', 'h_data', 'h_rt', 'highp', 'exclusive', 'h_vmem', 'gpu', 'pe', 'slot', 'campus', 'wait_time', 'wtime'])
df = (df.astype(dtype={'group':'str', 'owner':'str', 'job_number':'int', 'submission_time':'datetime64[ns]', 'start_time':'datetime64[ns]', 'end_time':'datetime64[ns]', 'failed':'int', 'exit_status':'int', 'granted_pe':'str', 'slots':'int', 'task_number':'int', 'maxvmem':'float', 'h_data':'float', 'h_rt':'float', 'highp':'int', 'exclusive':'int', 'h_vmem':'float', 'gpu':'int', 'pe':'str', 'slot':'int', 'campus':'int', 'wait_time':'timedelta64[ns]', 'wtime':'timedelta64[ns]'}))
df

输出:

         group  owner  job_number      submission_time           start_time             end_time  failed  exit_status  granted_pe  slots  task_number       maxvmem  h_data  h_rt  highp  exclusive  h_vmem  gpu      pe  slot  campus       wait_time     wtime
      0  g1     u1     3902779     2018-09-27 21:38:06  2018-10-01 07:24:38  2018-10-01 08:00:42  0       0            single      1      55696         609865728.0  4.0     6.0   0      0          4.0     0    single  1     0      3 days 09:46:32  00:36:04  
4080243  g50    u92    4071923     2018-10-25 02:08:14  2018-10-27 01:41:58  2018-10-27 02:08:50  0       0            shared      1      119          7.654482e+08  2.5     1.5   0      1          16.0    0    shared  1     0      1 days 23:33:44  00:26:52
4080244  g50    u92    4071922     2018-10-25 02:08:11  2018-10-27 01:46:53  2018-10-27 02:08:53  0       0            shared      1      2208         1.074463e+09  2.5     1.5   0      10         24.0    0    shared  1     0      1 days 23:38:42  00:22:00

代码生成第一行。为了多样化,我又添加了几行。

有 203 个组,699 个所有者。有数千个作业:“作业”定义为作业编号、任务编号和提交时间的唯一组合。

我想创建一份整体报告和每组一份报告,两者都侧重于资源使用情况。

整体报告的组成部分

一般统计数据:

  • 计数、平均值、标准、最小值、25%、50%、75%、最大值(数值)
  • count、unique、top、freq(字符串)
  • count, first, last # time delta cols (time delta)

工作:

  • task_numbers 最多的job_number,提交次数最多的job_number
  • 作业(如上定义)最早/最新
    • submission_time、start_time 和 end_time
  • 工作最多
    • 失败!= 0
    • exit_status != 0
  • 具有最多(值总和)的作业
    • granted_pe、slots、maxvmem、h_data、h_rt、exclusive、h_vmem 和 gpu
  • 最多的工作(计数/长度)
    • pe == 单人
    • pe == 共享
    • pe == 对于每个 addtl 类别的 pe
  • 累计最长/最短的作业
    • wait_time 和 wtime

所有者:

  • 拥有最多工作的所有者
  • 拥有最早/最新的所有者
    • 提交时间、开始时间、结束时间
  • 拥有最多
    • 失败!= 0
    • exit_status != 0
  • 拥有最多(值总和)的所有者
    • granted_pe、slots、maxvmem、h_data、h_rt、独占、h_vmem、gpu
  • 拥有最多 (count/len) 的所有者
    • pe == 单身
    • pe == 共享
    • pe == 对于每个 addtl 类别的 pe
  • 拥有最长/最短累积的所有者
    • wait_time 和 wtime

组:

  • 工作最多的组
  • 拥有最多所有者的组
  • 最早/最新的组
    • submission_time、start_time 和 end_time
  • 最多的组
    • 失败!= 0
    • exit_status != 0
  • 每个组中最多(值总和)的组
    • granted_pe、slots、maxvmem、h_data、h_rt、exclusive、h_vmem 和 gpu
  • 最多的组
    • pe == 单身
    • pe == 共享
    • pe == 对于每个 addtl 类别的 pe
  • 累计最长/最短的组
    • wait_time 和 wtime

个别“按组”报告的组成部分

按特征(df 中的列):

一般统计数据:

  • 计数、平均值、标准、最小值、25%、50%、75%、最大值(数值)
  • count、unique、top、freq(字符串)
  • count, first, last # time delta cols (time delta)

该组的统计数据:

按工作:

  • task_numbers 最多的job_number,submission_times 最多的job_number
  • 作业(如上定义)最早/最新
    • submission_time、start_time 和 end_time
  • 工作最多
    • 失败!= 0
    • exit_status != 0
  • 工作最多
    • granted_pe、slots、maxvmem、h_data、h_rt、exclusive、h_vmem 和 gpu
  • 工作最多
    • pe == 单个(计数/长度)
    • pe == 共享(计数/长度)
    • pe == 每个 addtl 类别的 pe (count/len)
  • 累计最长/最短的作业
    • wait_time 和 wtime

所有者:

  • 拥有最多工作的所有者
  • 拥有最早/最新的所有者
    • 提交时间、开始时间、结束时间
  • 拥有最多
    • 失败!= 0
    • exit_status != 0
  • 拥有最多
    • granted_pe、slots、maxvmem、h_data、h_rt、exclusive、h_vmem 和 gpu
  • 拥有最多
    • pe == 单个(计数/长度)
    • pe == 共享(计数/长度)
    • pe == 每个 addtl 类别的 pe (count/len)
  • 拥有最长/最短累积的所有者
    • wait_time 和 wtime

按排名:

在这里,我希望每个组与所有其他组进行排名,从使用率最高或“失败”最多的 1 到最低使用率的 203。我将使用这些值为每个组绘制图表。

排名:

  • 数量
    • jobs、job_numbers、task_numbers、提交时间
  • 第一次的时间
    • 提交时间、开始时间、结束时间
  • 上次时间
    • 提交时间、开始时间、结束时间
  • 数量
    • 失败!= 0
    • exit_status != 0
  • 数量
    • granted_pe、slots、maxvmem、h_data、h_rt、exclusive、h_vmem 和 gpu
  • 数量
    • pe == 单身
    • pe == 共享
    • pe == 用于每个 addtl 类别的 pe
  • 所有作业的总累计
    • wait_time 和 wtime

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    您可以使用 pandas .loc 以更简单的方式做到这一点

    初始化数据框:

    df = pd.DataFrame({'group':['e','e','e','h','h','h'],
                       'feature':['fail', 'exit', 'job', 'exit', 'fail', 'job'],
                       'cats':[1, 1, 1, 5, 2, 2],
                       'jobs':[1, 1, 1, 64, 64, 64],
                       'rank':[-1, -1, -1, -1, -1, -1],
                       'topvalue':[100, 0, 4, 37, 0, 3.9],
                       'freq':[1, 1, 1, 58, 63, 61]
    })
    

    我们想要对职位特征进行排名,因此我们只需使用.loc 隔离排名位置,然后在分配的右侧,我们使用.loc 隔离职位列并使用.rank() 函数

    按职位价值对职位特征进行排名:

    df.loc[df.feature == 'job', 'rank'] = df.loc[df.feature == 'job', 'jobs'].rank(ascending=False)
    

    按最高值不为 0 的频率对失败特征进行排序:

    对于这个,你确实对那些似乎与你所说的背道而驰的 0 进行了排名。所以我们将采用两种方式。

    通过这种方式,我们过滤掉 0 开始,并对其他所有内容进行排名。这将使top_value == 0 排名保持为-1

    df.loc[(df.feature == 'fail') & (df.topvalue != 0), 'rank'] = (
            df.loc[(df.feature == 'fail') & (df.topvalue != 0), 'freq']).rank(ascending=True)
    

    这样我们就不会过滤掉 0。

    df.loc[(df.feature == 'fail') & (df.topvalue != 0), 'rank'] = (
            df.loc[(df.feature == 'fail') & (df.topvalue != 0), 'freq']).rank(ascending=True)
    

    【讨论】:

    • 这看起来很有希望,但是当我测试它时,我意识到我的 df 实际上是一个 GroupBy 对象。错误消息建议使用.apply() 方法。我该怎么办?
    • for feat2 in features2: grouped = df.groupby('group')[feat2] grouped.loc[grouped.feature == 'job', 'rank'] = grouped.loc[grouped.feature == 'job', 'jobs'].rank(ascending=False) --> "AttributeError: 无法访问 'SeriesGroupBy' 对象的可调用属性 'loc',尝试使用 'apply' 方法"
    • 不要在功能部分做壮举。不要按数据框分组。保持原样。
    • 如果你有很多像 20+ 这样的特性,你需要这样做,并且它们每个使用不同的列进行排名,那么我建议创建 1 列与排名值,并且根据该 1 列进行分组和排名。
    • 我找到了一个适合我的答案here。它使用 groupby 和 loc/iloc。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-18
    • 2012-06-01
    相关资源
    最近更新 更多