我遇到了一个在pandas
中对布尔值进行重采样的特殊属性。以下是一些时间序列数据:
import pandas as pd
import numpy as np
dr = pd.date_range('01-01-2020 5:00', periods=10, freq='H')
df = pd.DataFrame({'Bools':[True,True,False,False,False,True,True,np.nan,np.nan,False],
"Nums":range(10)},
index=dr)
因此,数据如下所示:
Bools Nums
2020-01-01 05:00:00 True 0
2020-01-01 06:00:00 True 1
2020-01-01 07:00:00 False 2
2020-01-01 08:00:00 False 3
2020-01-01 09:00:00 False 4
2020-01-01 10:00:00 True 5
2020-01-01 11:00:00 True 6
2020-01-01 12:00:00 NaN 7
2020-01-01 13:00:00 NaN 8
2020-01-01 14:00:00 False 9
我本以为在重新采样时可以对布尔列执行简单操作(如求和),但(按现状)这失败了:
>>> df.resample('5H').sum()
Nums
2020-01-01 05:00:00 10
2020-01-01 10:00:00 35
“Bools”列被删除。我对发生这种情况的印象是b/c列的dtype
是object
。改变这种做法可以解决这个问题:
>>> r = df.resample('5H')
>>> copy = df.copy() #just doing this to preserve df for the example
>>> copy['Bools'] = copy['Bools'].astype(float)
>>> copy.resample('5H').sum()
Bools Nums
2020-01-01 05:00:00 2.0 10
2020-01-01 10:00:00 2.0 35
但是(奇怪的是,仍然可以通过索引重采样对象而不更改dtype
来对布尔值求和:
>>> r = df.resample('5H')
>>> r['Bools'].sum()
2020-01-01 05:00:00 2
2020-01-01 10:00:00 2
Freq: 5H, Name: Bools, dtype: int64
而且,如果唯一的列是布尔值,您仍然可以重新采样(尽管该列仍然是object
):
>>> df.drop(['Nums'],axis=1).resample('5H').sum()
Bools
2020-01-01 05:00:00 2
2020-01-01 10:00:00 2
是什么让后两个例子起作用?我可以看出它们可能更明确一些(“请,我真的想对这个列重新采样!”),但我不明白为什么原始的resample
不允许这个操作(如果可以的话)
那么追踪显示,
在groupby.py中跟踪
groupby_function
表明它相当于r.agg(lambda x: np.sum(x, axis=r.axis))
其中r = df.resample('5H')
输出:实际上,它应该是
r = df.resample('5H')['Bool']
(仅适用于上述情况)追踪resample.py中的
_downsample
函数可以发现它相当于:df.groupby(r.grouper, axis=r.axis).agg(np.sum)
输出:df.resample('5H').sum()
对Bools
列不起作用,因为该列具有混合数据类型,在pandas中为object
。在resample
或groupby
上调用sum()
时,将忽略object
类型的列相关问题 更多 >
编程相关推荐