我想使用“计数”列按日期和时间组合对数据集进行“修改”的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
挑战是,我想计算一个也计入未录入的中位数。
在数据集中,每个“日期”和“时间”组合最多有6行,因为数据是从6个单独的位置收集的。但是,如果特定日期/时间/地点组合的“计数”为0,则数据不会直接输入到数据集中。
(我已在上面的示例数据中删除了“位置”列,但是如果需要的话,它是可用的。)
这意味着,如果我使用通常的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
我该如何实现?有没有比我上面写的更有效的逻辑来解决这个问题?
预先感谢
答案 0 :(得分:1)
您可以在DataFrame.sort_values
之前的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'))