使用 groupby 添加标志列 top/bottom N 个值
Adding flags column top/bottom N values with groupby
我的 CSV 文件中有数据从 1/1/2015 00:00 到 1/1/2021 00:00 每小时,ID 为 ID15000。
我的目标是始终标记每个 ID 每天最好(标记 1)和最差(标记 2)4 个价格。因此,每天都会有 4x flag 1 和 4x flag 2,其余的 (16x flag0)
我想我应该先把这个table融化为数据库格式,然后应用一些pandas脚本如下。这也是我的小 CSV 文件。
https://github.com/mocukutli/analytics/blob/master/file.csv
import pandas as pd
df = pd.read_csv("file.csv",header=0,delimiter=",")
df=df.melt(
id_vars='Date',
var_name='ids',
value_name='price')
df['large']=df.index.isin(df.groupby('Date').price.nlargest(4).index.get_level_values(1)).astype(int)
df['small']=df.index.isin(df.groupby('Date').price.nsmallest(4).index.get_level_values(1)).astype(int)
df['flag']=df.small*2+df.large
print(df.head(24))
输出
Date ids price large small flag
0 1.01.2015 00:00 ID1 28.03 1 1 3
1 1.01.2015 01:00 ID1 28.02 1 1 3
2 1.01.2015 02:00 ID1 28.09 1 1 3
3 1.01.2015 03:00 ID1 27.41 1 1 3
4 1.01.2015 04:00 ID1 26.22 1 1 3
5 1.01.2015 05:00 ID1 27.33 1 1 3
6 1.01.2015 06:00 ID1 28.75 1 1 3
7 1.01.2015 07:00 ID1 28.78 1 1 3
8 1.01.2015 08:00 ID1 29.55 1 1 3
9 1.01.2015 09:00 ID1 28.32 1 1 3
10 1.01.2015 10:00 ID1 27.67 1 1 3
11 1.01.2015 11:00 ID1 26.79 1 1 3
12 1.01.2015 12:00 ID1 25.71 1 1 3
13 1.01.2015 13:00 ID1 24.42 1 1 3
14 1.01.2015 14:00 ID1 25.01 1 1 3
15 1.01.2015 15:00 ID1 24.55 1 1 3
16 1.01.2015 16:00 ID1 28.66 1 1 3
17 1.01.2015 17:00 ID1 29.47 1 1 3
18 1.01.2015 18:00 ID1 29.10 1 1 3
19 1.01.2015 19:00 ID1 28.64 1 1 3
20 1.01.2015 20:00 ID1 27.27 1 1 3
21 1.01.2015 21:00 ID1 26.32 1 1 3
22 1.01.2015 22:00 ID1 25.70 1 1 3
23 1.01.2015 23:00 ID1 24.60 1 1 3
如上所示,标志未正确分配。
一些想法和问题;
- 我不知道如何将日期列设置为“日期”,因为它是时间序列格式,我什至不确定 python 从 CSV 文件中读取该格式,所以一个问题可能是因为这个.
- 我通过从 1 到 2190 手动将该日期列转换为天数(考虑到从 2015 年到 2020 年有 2190 天),但是,nlargest 效果不佳,可能是因为索引问题..
- 做group by的时候,大小脚本也要实现id吗?
- 我的电脑马力不错,我得自己动手。我应该将熔化和标记部分分成两部分吗?
- 我应该为 PyCharm 做任何性能设置吗?即,使用 CPU..
的 %100
谢谢大家。
Pandas可以在加载csv文件时将字符串转换为日期,也可以在加载后进行转换
df = pd.read_csv("file.csv", header=0, delimiter=",", parse_dates=['Date'], infer_datetime_format=True)
然后您可以使用 resample
方法,它作为 groupby
用于 datetime64ns
列或索引的专用方法。
这是我们找到的答案;
import pandas as pd
import datetime
def date_parser(d):
d = datetime.datetime.strptime(str(d),"%d.%m.%Y %H:%M")
return d
df = pd.read_csv("file.csv",header=0,delimiter=",",parse_dates=['Date'],date_parser=date_parser)
#Splitting Date column to date and time
df["time"] = df["Date"].dt.time
df["Date"] = df["Date"].dt.date
df=df.melt(
id_vars=['Date','time'],
var_name='ids',
value_name='price')
df['large']=df.index.isin(df.groupby(['Date','ids']).price.nlargest(4).index.get_level_values(2)).astype(int)
df['small']=df.index.isin(df.groupby(['Date','ids']).price.nsmallest(4).index.get_level_values(2)).astype(int)
df['flag']=df.small*2+df.large
#Joining date and time column back to one Date column
df['Date']=df['Date'].astype('str') +' '+ df['time'].astype('str')
打印(df)
我的 CSV 文件中有数据从 1/1/2015 00:00 到 1/1/2021 00:00 每小时,ID 为 ID15000。
我的目标是始终标记每个 ID 每天最好(标记 1)和最差(标记 2)4 个价格。因此,每天都会有 4x flag 1 和 4x flag 2,其余的 (16x flag0)
我想我应该先把这个table融化为数据库格式,然后应用一些pandas脚本如下。这也是我的小 CSV 文件。
https://github.com/mocukutli/analytics/blob/master/file.csv
import pandas as pd
df = pd.read_csv("file.csv",header=0,delimiter=",")
df=df.melt(
id_vars='Date',
var_name='ids',
value_name='price')
df['large']=df.index.isin(df.groupby('Date').price.nlargest(4).index.get_level_values(1)).astype(int)
df['small']=df.index.isin(df.groupby('Date').price.nsmallest(4).index.get_level_values(1)).astype(int)
df['flag']=df.small*2+df.large
print(df.head(24))
输出
Date ids price large small flag
0 1.01.2015 00:00 ID1 28.03 1 1 3
1 1.01.2015 01:00 ID1 28.02 1 1 3
2 1.01.2015 02:00 ID1 28.09 1 1 3
3 1.01.2015 03:00 ID1 27.41 1 1 3
4 1.01.2015 04:00 ID1 26.22 1 1 3
5 1.01.2015 05:00 ID1 27.33 1 1 3
6 1.01.2015 06:00 ID1 28.75 1 1 3
7 1.01.2015 07:00 ID1 28.78 1 1 3
8 1.01.2015 08:00 ID1 29.55 1 1 3
9 1.01.2015 09:00 ID1 28.32 1 1 3
10 1.01.2015 10:00 ID1 27.67 1 1 3
11 1.01.2015 11:00 ID1 26.79 1 1 3
12 1.01.2015 12:00 ID1 25.71 1 1 3
13 1.01.2015 13:00 ID1 24.42 1 1 3
14 1.01.2015 14:00 ID1 25.01 1 1 3
15 1.01.2015 15:00 ID1 24.55 1 1 3
16 1.01.2015 16:00 ID1 28.66 1 1 3
17 1.01.2015 17:00 ID1 29.47 1 1 3
18 1.01.2015 18:00 ID1 29.10 1 1 3
19 1.01.2015 19:00 ID1 28.64 1 1 3
20 1.01.2015 20:00 ID1 27.27 1 1 3
21 1.01.2015 21:00 ID1 26.32 1 1 3
22 1.01.2015 22:00 ID1 25.70 1 1 3
23 1.01.2015 23:00 ID1 24.60 1 1 3
如上所示,标志未正确分配。
一些想法和问题;
- 我不知道如何将日期列设置为“日期”,因为它是时间序列格式,我什至不确定 python 从 CSV 文件中读取该格式,所以一个问题可能是因为这个.
- 我通过从 1 到 2190 手动将该日期列转换为天数(考虑到从 2015 年到 2020 年有 2190 天),但是,nlargest 效果不佳,可能是因为索引问题..
- 做group by的时候,大小脚本也要实现id吗?
- 我的电脑马力不错,我得自己动手。我应该将熔化和标记部分分成两部分吗?
- 我应该为 PyCharm 做任何性能设置吗?即,使用 CPU.. 的 %100
谢谢大家。
Pandas可以在加载csv文件时将字符串转换为日期,也可以在加载后进行转换
df = pd.read_csv("file.csv", header=0, delimiter=",", parse_dates=['Date'], infer_datetime_format=True)
然后您可以使用 resample
方法,它作为 groupby
用于 datetime64ns
列或索引的专用方法。
这是我们找到的答案;
import pandas as pd
import datetime
def date_parser(d):
d = datetime.datetime.strptime(str(d),"%d.%m.%Y %H:%M")
return d
df = pd.read_csv("file.csv",header=0,delimiter=",",parse_dates=['Date'],date_parser=date_parser)
#Splitting Date column to date and time
df["time"] = df["Date"].dt.time
df["Date"] = df["Date"].dt.date
df=df.melt(
id_vars=['Date','time'],
var_name='ids',
value_name='price')
df['large']=df.index.isin(df.groupby(['Date','ids']).price.nlargest(4).index.get_level_values(2)).astype(int)
df['small']=df.index.isin(df.groupby(['Date','ids']).price.nsmallest(4).index.get_level_values(2)).astype(int)
df['flag']=df.small*2+df.large
#Joining date and time column back to one Date column
df['Date']=df['Date'].astype('str') +' '+ df['time'].astype('str')
打印(df)