python-3.x - 按日期时间索引的 pandas 数据框中最常出现的情况

标签 python-3.x pandas datetime group-by resampling

我有一个很大的DataFrame,它按日期时间索引,特别是按天索引。我正在寻找一个高效的函数,对于每一列,检查每周最常见的非空值,并输出一个数据帧,该数据帧按周索引,由这些周内最常见的值组成。

这是一个例子。以下 DataFrame 包含两周的每日数据:

                        0      1    
2015-11-12 00:00:00     8     nan   
2015-11-13 00:00:00     7     nan   
2015-11-14 00:00:00     nan   5   
2015-11-15 00:00:00     7     nan   
2015-11-16 00:00:00     8     nan   
2015-11-17 00:00:00     7     nan   
2015-11-18 00:00:00     5     nan   
2015-11-19 00:00:00     9     nan   
2015-11-20 00:00:00     8     nan   
2015-11-21 00:00:00     6     nan   
2015-11-22 00:00:00     6     nan   
2015-11-23 00:00:00     6     nan   
2015-11-24 00:00:00     6     nan   
2015-11-25 00:00:00     2     nan   

并且应该转换成:

                        0    1    
2015-11-12 00:00:00     7    5
2015-11-19 00:00:00     6    nan

我的DataFrame非常大,因此效率很重要。谢谢。

编辑:如果可能的话,有人可以建议一种适用于条目是元组(而不是我的示例中的 float )的方法吗?

最佳答案

您可以使用resample按每周间隔对数据进行分组。然后,通过 pd.value_counts 计算出现次数,并使用 idxmax 选择最常见的:

df.resample("7D").apply(lambda x: x.apply(pd.value_counts).idxmax())

                     0      1
2015-11-12 00:00:00  7.0    5.0
2015-11-19 00:00:00  6.0    NaN

编辑

这是另一个 numpy 版本,它比上面的解决方案更快:

def numpy_mode(series):
    values = series.values
    dropped = values[~np.isnan(values)]

    # check for empty array and return NaN
    if not dropped.size:
        return np.NaN

    uniques, counts = np.unique(series.dropna(), return_counts=True)
    return uniques[np.argmax(counts)]

df2.resample("7D").apply(lambda x: x.apply(get_mode))

                     0      1
2015-11-12 00:00:00  7.0    5.0
2015-11-19 00:00:00  6.0    NaN

这里是基于虚拟数据的计时(为了进一步改进,请查看 here ):

%%timeit
df2.resample("7D").apply(lambda x: x.apply(pd.value_counts).idxmax())
>>> 100 loops, best of 3: 18.6 ms per loop

%%timeit 
df2.resample("7D").apply(lambda x: x.apply(get_mode))
>>> 100 loops, best of 3: 3.72 ms per loop

我也尝试过scipy.stats.mode但它也比 numpy 解决方案慢:

size = 1000
index = pd.DatetimeIndex(start="2012-12-12", periods=size, freq="D")
dummy = pd.DataFrame(np.random.randint(0, 20, size=(size, 50)), index=index)
print(dummy.head)

            0   1   2   3   4   5   6   7   8   9   ...     40  41  42  43  44  45  46  47  48  49
2012-12-12  18  2   7   1   7   9   16  2   19  19  ...     10  2   18  16  15  10  7   19  9   6
2012-12-13  7   4   11  19  17  10  18  0   10  7   ...     19  11  5   5   11  4   0   16  12  19
2012-12-14  14  0   14  5   1   11  2   19  5   9   ...     2   9   4   2   9   5   19  2   16  2
2012-12-15  12  2   7   2   12  12  11  11  19  5   ...     16  0   4   9   13  5   10  2   14  4
2012-12-16  8   15  2   18  3   16  15  0   14  14  ...     18  2   6   13  19  10  3   16  11  4 

%%timeit
dummy.resample("7D").apply(lambda x: x.apply(get_mode))
>>> 1 loop, best of 3: 926 ms per loop

%%timeit
dummy.resample("7D").apply(lambda x: x.apply(pd.value_counts).idxmax())
>>> 1 loop, best of 3: 5.84 s per loop

%%timeit
dummy.resample("7D").apply(lambda x: stats.mode(x).mode)
>>> 1 loop, best of 3: 1.32 s per loop

关于python-3.x - 按日期时间索引的 pandas 数据框中最常出现的情况,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43120291/

相关文章:

python - 使用 Pomegranate 拟合 Beta 分布

python-3.x - 根据现有列中的值创建新列

python - Pandas groupby 列值的变化

python - reshape MultiIndex 以分离

sql - 没有日期函数的 SQL 日期有什么用?

python - 如何使用 groupby 和过滤数据框来创建新列

python - 为什么这个切片示例在 NumPy 中的工作方式与它在标准列表中的工作方式不同?

mysql - 没有使用 SubSonic 3 Linq 从 MySQL 填充日期时间值

javascript - 如何返回按特定偏移量移动的小时 : minute string,?

python - 如何在 Kivy TextInput 中使用 .svg 图形?