我是python的新手并且正在努力解决以下问题;
我有以下字段的数据框构建:日期','机器类型','总运行时间'
Date Machine TRH
27-02-2018 ... ...
01-03-2018 A 2200
01-03-2018 B 5700
02-03-2018 A 2204
09-03-2018 B 5709
15-03-2018 B 5715
18-03-2018 A 2214
25-03-2018 A 2222
29-03-2018 B 5720
31-03-2018 A 2230
01-04-2018 ... ...
我想确定每种类型的机器运行的每月小时数,并将其存储在附加列中。
每月营业时间可由下一个公式决定: 本月持续日期的小时数 - 该月第一天的小时数
对于机器A:(2230 - 2200)= 30
对于机器B:(5720 - 5700)= 20
结果应该是:
Date Machine TRH Monthly TRH
27-02-2018 ... ... ...
01-03-2018 A 2200 30
01-03-2018 B 5700 20
02-03-2018 A 2204 30
09-03-2018 B 5709 20
15-03-2018 B 5715 20
18-03-2018 A 2214 30
25-03-2018 A 2222 30
29-03-2018 B 5720 20
31-03-2018 A 2230 30
01-04-2018 ... ... ...
我不知道如何解决这个问题。我应该使用groupby吗?我应该参考labda吗?我希望你们中的一个能回答我的问题。非常感谢!
答案 0 :(得分:1)
'''
Date Machine TRH
01-03-2018 A 2200
01-03-2018 B 5700
02-03-2018 A 2204
09-03-2018 B 5709
15-03-2018 B 5715
18-03-2018 A 2214
25-03-2018 A 2222
29-03-2018 B 5720
31-03-2018 A 2230
'''
df = pd.read_clipboard()
df.Date = pd.to_datetime(df.Date, dayfirst = True)
df.set_index(pd.DatetimeIndex(df.Date), inplace = True)
df.TRH = pd.to_numeric(df.TRH).copy()
monthly = (df.groupby([pd.Grouper(freq = 'M'), 'Machine']).TRH.last() - df.groupby([pd.Grouper(freq = 'M'), 'Machine']).TRH.first()).to_frame(name = 'Monthly TRH').reset_index()
monthly['month'] = monthly.Date.dt.to_period('M')
monthly.drop('Date', axis = 1, inplace = True)
df['month'] = df.Date.dt.to_period('M')
df.merge(monthly).drop('month', axis = 1)
第一种方法更快,但这是另一种方法:
'''
Date Machine TRH
01-03-2018 A 2200
01-03-2018 B 5700
02-03-2018 A 2204
09-03-2018 B 5709
15-03-2018 B 5715
18-03-2018 A 2214
25-03-2018 A 2222
29-03-2018 B 5720
31-03-2018 A 2230
'''
# clean up
df = pd.read_clipboard().sort_values('Date')
df.Date = pd.to_datetime(df.Date, dayfirst = True)
df['month'] = df.Date.dt.to_period('M')
df.TRH = pd.to_numeric(df.TRH).copy()
# do it in one go
df.groupby([
'month',
'Machine'
]).nth([
0,
-1
]).groupby([
'month',
'Machine'
]).diff().drop(columns = 'Date').dropna().reset_index().rename(columns = {
'TRH' : 'Monthly TRH'
}).merge(df).drop(columns = 'month')
结果相同,列顺序不同。
答案 1 :(得分:0)
我猜测有人会提出比2组更好的方法,但这会有效。
首先对日期进行排序(确保它们是日期时间),然后将first
和last
与groupby机器和月份一起使用(如果数据超过1年,则使用年份)。
import pandas as pd
df['Date'] = pd.to_datetime(df.Date, format='%d-%m-%Y')
df['Year'] = df.Date.dt.year
df['Month'] = df.Date.dt.month
df.sort_values(by='Date', inplace=True)
temp = (df.groupby(['Machine', 'Year', 'Month'])['TRH'].last()-
df.groupby(['Machine', 'Year', 'Month'])['TRH'].first()).reset_index().rename(columns={'TRH': 'Monthly TRH'}
# Machine Year Month Monthly TRH
#0 A 2018 3 30.0
#1 B 2018 3 20.0
然后把它带回来你可以合并
df.merge(temp, on=['Month', 'Year', 'Machine'], how='left').drop(columns=['Month', 'Year'])
# Date Machine TRH Monthly TRH
#0 2018-02-27 ... ... ...
#1 2018-03-01 A 2200.0 30.0
#2 2018-03-02 A 2204.0 30.0
#3 2018-03-18 A 2214.0 30.0
#4 2018-03-25 A 2222.0 30.0
#5 2018-03-31 A 2230.0 30.0
#6 2018-03-01 B 5700.0 20.0
#7 2018-03-09 B 5709.0 20.0
#8 2018-03-15 B 5715.0 20.0
#9 2018-03-29 B 5720.0 20.0
#10 2018-04-01 ... ... ...