【发布时间】:2017-01-23 10:15:06
【问题描述】:
我编写了以下代码来预处理这样的数据集:
StartLocation StartTime EndTime
school Mon Jul 25 19:04:30 GMT+01:00 2016 Mon Jul 25 19:04:33 GMT+01:00 2016
... ... ...
它包含用户参加的地点列表以及开始和结束时间。每个位置可能会出现多次,并且没有完整的位置列表。由此,我想汇总每个位置的数据(频率、总时间、平均时间)。为此,我编写了以下代码:
def toEpoch(x):
try:
x = datetime.strptime(re.sub(r":(?=[^:]+$)", "", x), '%a %b %d %H:%M:%S %Z%z %Y').strftime('%s')
except:
x = datetime.strptime(x, '%a %b %d %H:%M:%S %Z %Y').strftime('%s')
x = (int(x)/60)
return x
#Preprocess data
df = pd.read_csv('...')
for index, row in df.iterrows():
df['StartTime'][index] = toEpoch(df['StartTime'][index])
df['EndTime'][index] = toEpoch(df['EndTime'][index])
df['TimeTaken'][index] = int(df['EndTime'][index]) - int(df['StartTime'][index])
total = df.groupby(df['StartLocation'].str.lower()).sum()
av = df.groupby(df['StartLocation'].str.lower()).mean()
count = df.groupby(df['StartLocation'].str.lower()).count()
output = pd.DataFrame({"location": total.index, 'total': total['TimeTaken'], 'mean': av['TimeTaken'], 'count': count['TimeTaken']})
print(output)
这段代码运行正常,但是效率很低。如何优化代码?
编辑:基于 @Batman's 有用的 cmets 我不再迭代。但是,如果可能的话,我仍然希望进一步优化这一点。更新后的代码是:
df = pd.read_csv('...')
df['StartTime'] = df['StartTime'].apply(toEpoch)
df['EndTime'] = df['EndTime'].apply(toEpoch)
df['TimeTaken'] = df['EndTime'] - df['StartTime']
total = df.groupby(df['StartLocation'].str.lower()).sum()
av = df.groupby(df['StartLocation'].str.lower()).mean()
count = df.groupby(df['StartLocation'].str.lower()).count()
output = pd.DataFrame({"location": total.index, 'total': total['TimeTaken'], 'mean': av['TimeTaken'], 'count': count['TimeTaken']})
print(output)
【问题讨论】:
-
你应该只分组一次,然后得到
sum、mean和count -
你真的需要
.str.lower()吗?你真的需要正则表达式吗? -
@furas 位置是手动输入的,所以它是必要的,正则表达式是用来处理不寻常的时间戳。 (见this)
-
使用
apply仍在迭代中。
标签: python datetime pandas optimization dataframe