如何计算接触事件的顺序?
How can I calculate sequences of contact events?
我有一个表示肿瘤之间接触事件的数据集。数据集按“base-tumor”分组,然后按“Neighbor-tumor”和“Time-frame”排序,如下所示:
index
base-tumor
neighbor-tumor
timeframe
0
Track_1
Track_4
1
1
Track_1
Track_4
2
2
Track_1
Track_4
3
3
Track_1
Track_4
4
4
Track_1
Track_4
8
5
Track_1
Track_4
9
6
Track_1
Track_4
10
7
Track_1
Track_6
1
8
Track_1
Track_6
2
因为数据框是按基础肿瘤分组的,所以我有多个具有升序基础肿瘤的数据框。
我试图得到的最终结果是一个包含所有轨道的字典,其中包含一个包含所有轨道的字典,其中有一个接触事件,然后它们包含一个帧列表,其中有一个接触事件的顺序。它看起来像这样:
{Track_1: {Track_4: [[1,4], [8,10],
Track_6: [[1,2]]},
Track_2: {Track_5: [[10, 14], [20, 25], [28, 31]}}
到目前为止,我所做的是,我制作了一个额外的列,如果有接触事件序列则显示 1,如果没有接触事件序列则显示 0。
def get_sequence(df):
for id, grp in df:
prev_id = grp['id_2'].shift(1).fillna(0)
prev_frame = grp['FRAME'].shift(1)
conditions = [
((grp['id_2'] == prev_id) &
(grp['FRAME']) - prev_frame == 1)
]
choises = [1]
grp['sequence'] = np.select(conditions, choises, default=0)
print(grp)
现在我被卡住了,不知道我的方向是否正确,如果正确,下一步该怎么做。
这是一种方法:
# Identify continuous timeframes.
df['consec'] = df.groupby(['base-tumor', 'neighbor-tumor'])['timeframe'].transform(lambda s: s.diff().ne(1).cumsum())
# Get timeframe intervals.
t_df = (df.groupby(['base-tumor', 'neighbor-tumor', 'consec']).
agg(t_start=('timeframe', 'first'), t_end=('timeframe', 'last')).
droplevel(-1)
)
t_df = t_df[t_df['t_start'].ne(t_df['t_end'])]
t_df['interval'] = list(zip(t_df['t_start'], t_df['t_end']))
# Convert to dictionary.
result = {k: g.droplevel(0)['interval'].groupby(level=0).agg(list).to_dict()
for k, g in t_df.drop(columns=['t_start', 't_end']).groupby(level=0)}
print(result)
{'Track_1': {'Track_4': [(1, 4), (8, 10)], 'Track_6': [(1, 2)]}}
我有一个表示肿瘤之间接触事件的数据集。数据集按“base-tumor”分组,然后按“Neighbor-tumor”和“Time-frame”排序,如下所示:
index | base-tumor | neighbor-tumor | timeframe |
---|---|---|---|
0 | Track_1 | Track_4 | 1 |
1 | Track_1 | Track_4 | 2 |
2 | Track_1 | Track_4 | 3 |
3 | Track_1 | Track_4 | 4 |
4 | Track_1 | Track_4 | 8 |
5 | Track_1 | Track_4 | 9 |
6 | Track_1 | Track_4 | 10 |
7 | Track_1 | Track_6 | 1 |
8 | Track_1 | Track_6 | 2 |
因为数据框是按基础肿瘤分组的,所以我有多个具有升序基础肿瘤的数据框。
我试图得到的最终结果是一个包含所有轨道的字典,其中包含一个包含所有轨道的字典,其中有一个接触事件,然后它们包含一个帧列表,其中有一个接触事件的顺序。它看起来像这样:
{Track_1: {Track_4: [[1,4], [8,10],
Track_6: [[1,2]]},
Track_2: {Track_5: [[10, 14], [20, 25], [28, 31]}}
到目前为止,我所做的是,我制作了一个额外的列,如果有接触事件序列则显示 1,如果没有接触事件序列则显示 0。
def get_sequence(df):
for id, grp in df:
prev_id = grp['id_2'].shift(1).fillna(0)
prev_frame = grp['FRAME'].shift(1)
conditions = [
((grp['id_2'] == prev_id) &
(grp['FRAME']) - prev_frame == 1)
]
choises = [1]
grp['sequence'] = np.select(conditions, choises, default=0)
print(grp)
现在我被卡住了,不知道我的方向是否正确,如果正确,下一步该怎么做。
这是一种方法:
# Identify continuous timeframes.
df['consec'] = df.groupby(['base-tumor', 'neighbor-tumor'])['timeframe'].transform(lambda s: s.diff().ne(1).cumsum())
# Get timeframe intervals.
t_df = (df.groupby(['base-tumor', 'neighbor-tumor', 'consec']).
agg(t_start=('timeframe', 'first'), t_end=('timeframe', 'last')).
droplevel(-1)
)
t_df = t_df[t_df['t_start'].ne(t_df['t_end'])]
t_df['interval'] = list(zip(t_df['t_start'], t_df['t_end']))
# Convert to dictionary.
result = {k: g.droplevel(0)['interval'].groupby(level=0).agg(list).to_dict()
for k, g in t_df.drop(columns=['t_start', 't_end']).groupby(level=0)}
print(result)
{'Track_1': {'Track_4': [(1, 4), (8, 10)], 'Track_6': [(1, 2)]}}