Csv pandas groupby 中位数 'modified'

Csv pandas groupby with a 'modified' median

我想使用 'count' 列按日期和时间组合对数据集执行 'modified' df.groupby.median()。

下面是我正在使用的数据集示例:

              date    time    count
0         20160730    02:30     415
1         20160730    02:30      18
2         20160730    02:30      24
3         20160730    02:30      31
4         20160730    13:30      64
...            ...      ...     ...
169549    20170101    23:45      29
169550    20170101    23:45      34
169551    20170101    23:45      43
169552    20170101    23:45      42
169553    20170101    23:45      60

挑战在于,我想计算一个中位数,该中位数也考虑了非条目。

在数据集中,每个 'date' 和 '时间组合最多有 6 行,因为数据是从 6 个不同的位置收集的。但是,如果特定 date/time/location 组合的 'count' 为 0,则数据根本不会输入到数据集中。

(我在上面的示例数据中删除了 'location' 列,但如果需要它是可用的。)

这意味着如果我使用通常的 df.groupby.median() 函数,我会高估数据的真实中位数,因为它会忽略未输入的零。

本质上,我想计算一个修改后的中位数,如下所示:

For each date and time combination:
   count_rows = count number of rows that satisfy the date and time combination
   if count_rows == 6:
      mod_median = median of the 6 rows
   elif count_rows == 5 or count_rows == 4:
      mod_median = average of the 3rd and 4th highest row values
   elif count_rows == 3:
      mod_median = half of the lowest row value
      # true median == median of [0, 0, 0, value1, value2, value3]
   else
      mod_median = 0
      # true median == zero for count_rows <= 2

我怎样才能做到这一点?有没有比我上面写的更有效的逻辑来解决这个问题?

提前致谢

您可以使用自定义函数 DataFrame.sort_values before GroupBy.apply:

def cust_med(x):
    len1 = len(x.index)
    if len1 == 6:
        return x['count'].median()
    if (len1 == 5) or (len1 == 4):
        #3rd and 4th higher values
        return x.iloc[[2,3], x.columns.get_loc('count')].mean()
    if len1 == 3:
        #added 3 values with np.median
        return np.median(np.concatenate([[0,0,0], x['count']]))
    else:
        return 0

df = (df.sort_values(['date','time', 'count'], ascending=[True, True, False])
       .groupby(['date','time']).apply(cust_med)
       .reset_index(name='custom median'))