Python 分组浮点数

Python 分组浮点数,python,pandas,numpy,floating-point,Python,Pandas,Numpy,Floating Point,我有一个应用程序,需要根据时间戳(可能是浮点值)对数据列表(当前在.DataFrame中)进行块平均。例如,我可能需要将以下df平均分为0.3s组: +------+------+ +------+------+ | secs | A | | secs | A | +------+------+ +------+------+ | 0.1 | .. | | 0.3 | .. | <-- avg of 0

我有一个应用程序,需要根据时间戳(可能是浮点值)对数据列表(当前在.DataFrame
中)进行块平均。例如,我可能需要将以下
df
平均分为
0.3
s组:

+------+------+         +------+------+
| secs |  A   |         | secs |  A   |
+------+------+         +------+------+
| 0.1  |  ..  |         | 0.3  |  ..  | <-- avg of 0.1, 0.2, 0.3
| 0.2  |  ..  |   -->   | 0.6  |  ..  | <-- avg of 0.4, 0.5, 0.6
| 0.3  |  ..  |         | ...  | ...  | <-- etc
| 0.4  |  ..  |         +------+------+
| 0.5  |  ..  |
| 0.6  |  ..  |
| ...  | ...  |
+------+------+
对于整型
duration
s,它的效果很好,但是块边缘的浮点值可能落在错误的一侧。正确创建块的一个简单测试是,以数据已经存在的相同
持续时间
进行平均(
0.1
)。这应该会返回输入,但通常不会。(例如,
x=.1*np.arange(1,20);(x-x[0])/.1)

我发现这种方法的错误通常是LSB低1,所以一个暂时的解决办法是在
分组中的分子中添加
np.spating(df['secs'))
。(即,
x=.1*np.arange(1,20);all((x-x[0]+np.space(x))//.1==np.arange(19))
返回
True

然而,我担心这不是一个强有力的解决办法。是否有更好或首选的方法对通过上述测试的浮动进行分组

我在使用
x[(duration*I
In [11]: np.round(300 + df.secs * 1000).astype(int) // 300
Out[11]:
0    1
1    1
2    1
3    2
4    2
5    2
Name: secs, dtype: int64

In [12]: (np.round(300 + df.secs * 1000).astype(int) // 300) * 0.3
Out[12]:
0    0.3
1    0.3
2    0.3
3    0.6
4    0.6
5    0.6
Name: secs, dtype: float64

In [13]: df.groupby(by=(np.round(300 + df.secs * 1000).astype(int) // 300) * 0.3)["A"].sum()
Out[13]:
secs
0.3    1.753843
0.6    2.687098
Name: A, dtype: float64
我更喜欢使用时间增量:

In [21]: s = pd.to_timedelta(np.round(df["secs"], 1), unit="S")

In [22]: df["secs"] = pd.to_timedelta(np.round(df["secs"], 1), unit="S")

In [23]: df.groupby(pd.Grouper(key="secs", freq="0.3S")).sum()
Out[23]:
                        A
secs
00:00:00         1.753843
00:00:00.300000  2.687098
或使用
重新采样

In [24]: res = df.set_index("secs").resample("300ms").sum()

In [25]: res
Out[25]:
                        A
secs
00:00:00         1.753843
00:00:00.300000  2.687098
您可以设置索引以更正标签*

In [26]: res.index += np.timedelta64(300, "ms")

In [27]: res
Out[27]:
                        A
secs
00:00:00.300000  1.753843
00:00:00.600000  2.687098

*应该有一种方法通过重采样参数来设置,但它们似乎不起作用…

主要问题是浮点总是不准确的,您可以使用ms或ns(即
np.timedelta
)?@和yhayden不幸的是,我无法控制数据的写入方式。但是(目前)它总是1毫秒的整数倍,所以我可以
(…)*1000。如果必须的话,我可以键入(int)
。意识到浮点(几乎)总是不精确的,在一个(或两者)中填充
np.spating
真的不能保证吗方向?是的,这是一个不精确的东西,它会咬你,我想你可以先取整它?冒着误用注释部分的风险,浮动在LSB中只会偏离准确的预期值1(我的意思是在操纵之前)。问题是我不确定如何在浮点上执行
/
,因此我无法限制错误。如果结果表明错误限制是,比如说,5位,用
5*np填充。空格(…)
应该可以,对吧?我认为np.round将有助于规范化为int(并避免错误),添加了一个答案来建议(除其他外)这看起来很好,我认为我同意转换为MS是最好的。TBH,我以前从未听过<代码> TimeDela/Cord>,但看起来是一个非常好的工具。@ NIVK请考虑“接受”如果它对你有用:我一般不喜欢接受这么快(特别是在低视角问题),但我想我可以例外。(什么,126k对你来说还不够?;)
In [26]: res.index += np.timedelta64(300, "ms")

In [27]: res
Out[27]:
                        A
secs
00:00:00.300000  1.753843
00:00:00.600000  2.687098