我正在尝试查找两个成员之间的重叠之处,以了解他们是否彼此认识。我也有一个最低限度的重叠规定(即,他们需要彼此了解至少两个月才能组成一个小组)。
示例输入DF
time_together = 5184000 (60 days)
person_name start_date end_date cut_off (start + time_together)
sally 1540627200 1545638400 1545811200
john 1543046400 1548316800 1548230400
edgar 1548316800 1553414400 1553500800
我目前在熊猫数据框中的unix时间戳中有开始日期和结束日期。我已经计算出截止时间,即开始时间+最短持续时间。然后,我会检查每个参加者的截止日期,如果该次数少于我说的他们将组成一个有效的小组(请参见下面的代码)
df_new = pd.DataFrame()
for i in range(len(df.index)):
start_range = (df.loc[i,'cutoff'] - df['start_timestamp'] > 0)
end_range = (df.loc[i,'cutoff'] < df['end_timestamp'])
df_new['%s%s' % (df.loc[i,'Soldier_SSN'],i)] = start_range & end_range
问题是我现在有一个布尔矩阵,我需要生成一个具有组名的输出。 (有关理想的输出,请参见下文)。
电流输出DF:
sally john edgar
0 True True False
1 True True False
2 False False False
因为萨莉和约翰在一起时间最短。他们会组成一个小组,但埃德加却没有。
理想情况下,输出应为列表列表 [[person1,person2,person5],[person3,person4]]
这也太慢了,所以关于如何加快速度的任何建议都很棒。
答案 0 :(得分:2)
我认为您要实现的目标很多,但是可以分为两个步骤。 (而且我不确定这是否是实现目标的最有效方式)
对于第一个任务,一种简单的方法是遍历每个人并检查其他人是否有足够的重叠。
从测试DataFrame(伪随机时间和任意名称)开始:
index person_name start_date end_date
0 Angelina 1510568169 1523357075
1 Na 1555533506 1568322412
2 Twyla 1558758901 1571547807
3 Wilfredo 1551369432 1564158338
4 Estefana 1515025466 1527814372
我们可以找到以下对:
pairs = []
for i in range(len(test.index)):
for j in range(len(test.index)-i-1):
if (min(test.loc[i]['end_date'], test.loc[i+j+1]['end_date'])
- max(test.loc[i]['start_date'], test.loc[i+j+1]['start_date'])
>= (min_time_together)):
pairs.append([test.loc[i]['person_name'], test.loc[i+j+1]['person_name']])
这将生成输出:
[['Angelina', 'Estefana'],
['Na', 'Twyla'],
['Na', 'Wilfredo'],
['Twyla', 'Wilfredo']]
要“压缩”这对列表,涉及一堆图论,说实话,我不是BUT的专家,这里是一个amazing的答案,它回答了一个相关的StackOverflow问题(非常有趣的话题,还有很多该页面上的详细信息)。如果我们使用列表列表中答案的condenseBK
函数,则会得到以下最终输出:
#condenseBK(*pairs)
[['Angelina', 'Estefana'], ['Na', 'Twyla', 'Wilfredo']]