如何每天在特定列上聚合函数

Posted

技术标签:

【中文标题】如何每天在特定列上聚合函数【英文标题】:How to aggregate a function on a specific column for each day 【发布时间】:2021-04-09 02:54:40 【问题描述】:

我有一个包含分钟数据的 CSV 文件。

最终目标是使用每天的所有数据,找出每天所有低点('Low' 列)的标准差。

问题在于 csv 文件中存在一些漏洞,因为它没有正好 390 分钟(交易日的分钟数)。代码如下所示:

import pandas as pd
import datetime as dt


df = pd.read_csv('/Volumes/Seagate Portable/S&P 500 List/AAPL.txt')
df.columns = ['Extra', 'Dates', 'Open', 'High', 'Low', 'Close', 'Volume']
df.drop(['Extra', 'Open', 'High', 'Volume'], axis=1, inplace=True)
df.Dates = pd.to_datetime(df.Dates)
df.set_index(df.Dates, inplace=True)
df = df.between_time('9:30', '16:00')
print(df.Low[::390])

输出如下:

Dates
2020-01-02 09:30:00     73.8475
2020-01-02 16:00:00     75.0875
2020-01-03 15:59:00     74.3375
2020-01-06 15:58:00     74.9125
2020-01-07 15:57:00     74.5028
                         ...   
2020-12-14 09:41:00    122.8800
2020-12-15 09:40:00    125.9900
2020-12-16 09:39:00    126.5600
2020-12-17 09:38:00    129.1500
2020-12-18 09:37:00    127.9900
Name: Low, Length: 245, dtype: float64

正如您在输出中看到的那样,即使缺少一个 9:30,我也无法再按 390 索引。因此,我对此的解决方案是获取尽可能多的数据,即使在某种意义上缺少日期也就是说,当日期时间代码从 15:59 或 16:00 变为 9:31 或 9:32 时。本质上,当它在 16 点到 9:30 之间变回时?不知道有没有其他解决办法?有任何想法吗?如果这是解决方案,最好的编码方式是什么?

【问题讨论】:

【参考方案1】:'date' 上使用.groupby()pandas.Grouper(),在一天中使用freq='D',然后在'low' 上聚合.std()'date' 列必须是 datetime dtype。如果需要,使用pd.to_datetime() 转换'Dates' 列。 如果需要,使用df = df.set_index('date').between_time('9:30', '16:00').reset_index() 仅选择特定范围内的时间。这将在.groupby() 之前完成。 'date' 列必须是index,才能使用.between_time()
import requests
import pandas as pd

# sample stock data
periods = '3600'
resp = requests.get('https://api.cryptowat.ch/markets/poloniex/ethusdt/ohlc', params='periods': periods)
data = resp.json()
df = pd.DataFrame(data['result'][periods], columns=['date', 'open', 'high', 'low', 'close', 'volume', 'amount'])

# convert to a datetime format
df['date'] = pd.to_datetime(df['date'], unit='s')

# display(df.head())
                 date        open        high         low       close       volume        amount
0 2020-11-22 02:00:00  550.544464  554.812114  536.523241  542.000000  2865.381737  1.567462e+06
1 2020-11-22 03:00:00  541.485933  551.621355  540.992000  548.500000  1061.275481  5.796859e+05
2 2020-11-22 04:00:00  548.722267  549.751680  545.153196  549.441709   310.874748  1.703272e+05
3 2020-11-22 05:00:00  549.157866  549.499632  544.135302  546.913493   259.077448  1.416777e+05
4 2020-11-22 06:00:00  547.600000  548.000000  541.668524  544.241871   363.433373  1.979504e+05

# groupby day, using pd.Grouper and then get std of low
std = df.groupby(pd.Grouper(key='date', freq='D'))['low'].std().reset_index(name='low std')

# display(std)
         date    low std
0  2020-11-22  14.751495
1  2020-11-23  14.964803
2  2020-11-24   6.542568
3  2020-11-25   9.523858
4  2020-11-26  24.041421
5  2020-11-27   8.272477
6  2020-11-28  12.340238
7  2020-11-29   8.444779
8  2020-11-30  10.290333
9  2020-12-01  13.605846
10 2020-12-02   6.201248
11 2020-12-03   9.403853
12 2020-12-04  12.667251
13 2020-12-05  10.180626
14 2020-12-06   4.481538
15 2020-12-07   3.881311
16 2020-12-08  10.518746
17 2020-12-09  12.077622
18 2020-12-10   6.161330
19 2020-12-11   5.035066
20 2020-12-12   6.297173
21 2020-12-13   9.739574
22 2020-12-14   3.505540
23 2020-12-15   3.304968
24 2020-12-16  16.753780
25 2020-12-17  10.963064
26 2020-12-18   5.574997
27 2020-12-19   4.976494
28 2020-12-20   7.243917
29 2020-12-21  16.844777
30 2020-12-22  10.348576
31 2020-12-23  15.769288
32 2020-12-24  10.329158
33 2020-12-25   5.980148
34 2020-12-26   8.530006
35 2020-12-27  21.136509
36 2020-12-28  16.115898
37 2020-12-29  10.587339
38 2020-12-30   7.634897
39 2020-12-31   7.278866
40 2021-01-01   6.617027
41 2021-01-02  19.708119

【讨论】:

以上是关于如何每天在特定列上聚合函数的主要内容,如果未能解决你的问题,请参考以下文章

如何基于多个唯一列选择数据而不在结果集中的其余列上应用聚合函数

我们可以使用不同的过滤条件在同一个表字段或列上多次使用相同的聚合函数吗?

如何在 Hive 中按列分组使用聚合函数

MySQL:加入表并根据另一列上的聚合函数从一行返回一列[重复]

Pyspark - 一次聚合数据框的所有列[重复]

同一列上具有多个聚合的 T-SQL Pivot