我有一个Pandas数据帧(attendance_records)。它包含当地学校的出勤记录。
每行有4列:1)缺席的学生姓名(姓名),2)学生的地址(地址),3)缺席的第一天(开始),以及4)最后一天缺席日(结束)。
例如,一行可以是:
Bobby 101 1st Street 9/1/2014 9/3/2014
这意味着Bobby每天都在9/1和9/3(含)之间缺席。
我想按照以下方式展开表格:
Bobby 101 1st Street 9/1/2014
Bobby 101 1st Street 9/2/2014
Bobby 101 1st Street 9/3/2014
到目前为止,我有一些代码(下面)可以完成这项工作,但是对于大型表来说它实际上很慢,因为它基本上是逐行遍历表。关于如何让事情变得更快的任何想法?
import pandas as pd
def full_data(dataframe):
allframe = pd.DataFrame()
for i in dataframe.index:
newframe = pd.DataFrame()
newframe['dates'] = pd.date_range(dataframe.iloc[i].start, dataframe.iloc[i].end, freq = 'D')
newframe['name'] = dataframe.iloc[i]['name']
newframe['address'] = dataframe.iloc[i]['address']
allframe = allframe.append(newframe)
if i%1000 == 0:
print i
return allframe
attendance_records = full_data(attendance_records)
答案 0 :(得分:2)
对于较大的数据帧,pandas函数append
可能会很慢。相反,我建议将newframes
存储在python列表中,而不是使用concat函数将所有帧仅附加一次。
import pandas as pd
def full_data(dataframe):
allframes = []
for i in dataframe.index:
newframe = pd.DataFrame()
newframe['dates'] = pd.date_range(dataframe.iloc[i].start, dataframe.iloc[i].end, freq = 'D')
newframe['name'] = dataframe.iloc[i]['name']
newframe['address'] = dataframe.iloc[i]['address']
allframes.append(newframe)
return concat(allframes)
请注意,这尚未经过测试。
答案 1 :(得分:0)
对日期执行日期算术,您不需要填写缺失的日期。然后按名称分组并总计天数。
from datetime import timedelta
data = pd.read_csv(StringIO('''Bobby, 101 1st Street, 9/1/2014, 9/3/2014'''),
names=['Name', 'Address', 'Start', 'End'], parse_dates=[2, 3])
#add a day to get the number of days inclusive
data["Days"] = (data.End - data.Start) + timedelta(days=1)
data.groupby('name').sum()["Days"]