我有一个人员ID列表,对于每个ID,我想从两个不同的数据帧中提取所有可用信息。此外,信息类型也有ID,我只想要每个人ID的特定信息ID。以下是我目前的做法:
new_table = []
for i in range(ranges):
slice = pd.concat([df1[sp.logical_and(df1.person.values == persons[i],
df1['info_id'].isin(info_ids))],
df2[sp.logical_and(df2.person.values == persons[i],
df2['info_id'].isin(info_ids))]], ignore_index=True)
if len(list(set(slice['info_ids']))) < amount_of_info_needed:
continue
else:
full_time_range = max(slice['age_days']) - min(slice['age_days'])
if full_time_range <= 1460:
new_table.append(slice)
else:
window_end = min(slice['age_days']) + 1460
slice = slice[slice.age_days < window_end+1]
if len(list(set(slice['info_id']))) < amount_of_info_needed:
continue
else:
new_table.append(slice)
#return new_table
new_table = pd.concat(new_table, axis=0)
new_table = new_table.groupby(['person', 'info_id']).agg(np.mean).reset_index()
new_table.to_sql('person_info_within4yrs', engine, if_exists='append', index=False,
dtype={'person': types.NVARCHAR(32), 'value': types.NVARCHAR(4000)})
我读到因为二次时间而没有在循环中使用pd.concat,但我尝试将数据帧转换为数组并切片和连接,但这比使用pd.concat要慢。在使用%lprun对每一行进行分析之后,循环中的pd.concat / logical_and操作将消耗所有时间。此代码也比使用.loc和两个数据帧以及将两个切片连接在一起更快。在if-else块之后,我追加到列表,最后将列表转换为数据帧。
编辑:以下是我正在做的事情的一个例子。目标是通过person_id和info_id从两个数据帧中切片,组合切片,并将组合切片附加到列表中,然后我将返回到数据帧并导出到SQL表。 if-else块也是相关的,但是从我的分析中它们几乎没有任何时间,所以我不打算详细描述它们。
df1.head()
person info_id value age_days
0 000012eae6ea403ca564e87b8d44d0bb 0 100.0 28801
1 000012eae6ea403ca564e87b8d44d0bb 0 100.0 28803
2 000012eae6ea403ca564e87b8d44d0bb 0 100.0 28804
3 000012eae6ea403ca564e87b8d44d0bb 0 100.0 28805
4 000012eae6ea403ca564e87b8d44d0bb 0 100.0 28806
df2.head()
person info_id value age_days
0 00000554787a3cb38131c3c38578cacf 4v 97.0 12726
1 00000554787a3cb38131c3c38578cacf 14v 180.3 12726
2 00000554787a3cb38131c3c38578cacf 9v 2.0 12726
3 00000554787a3cb38131c3c38578cacf 3v 20.0 12726
4 00000554787a3cb38131c3c38578cacf 0v 71.0 12726
答案 0 :(得分:0)
我接受了Parfait的建议并首先将两个数据帧连接成一个,然后同事给了我一个迭代数据帧的解决方案。数据帧由~117M行和~246K人ID组成。我的同事的解决方案是创建一个字典,其中每个键都是一个人ID,每个键的值是数据帧中该人ID的行索引列表。然后使用.iloc通过引用字典中的值来对数据帧进行切片。大约一个小时就完成了跑步。
idx = df1['person'].reset_index().groupby('person')['index'].apply(tuple).to_dict()
for i in range(ranges):
mrn_slice = df1.iloc[list(idx.values()[i])]