Pandas 数据框与不同组的交集

Pandas dataframe intersection with varying groups

我有一个很大的 pandas 数据框,其中包含不同的行和列,但看起来或多或少像:

time   id    angle  ...
0.0    a1    33.67  ...
0.0    b2    35.90  ...
0.0    c3    42.01  ...
0.0    d4    45.00  ...
0.1    a1    12.15  ...
0.1    b2    15.35  ...
0.1    c3    33.12  ...
0.2    a1    65.28  ...
0.2    c3    87.43  ...
0.3    a1    98.85  ...
0.3    c3    100.12 ...
0.4    a1    11.11  ...
0.4    c3    83.22  ...
...

我正在尝试将 id's 聚合在一起,然后找到具有共同时间间隔的 id's。我试过使用 pandas groupby,可以很容易地按 id 对它们进行分组,并获得它们各自的组的信息。我怎样才能更进一步找到 id's 也有 相同的 时间戳?

理想情况下,我希望return某些固定时间间隔(2-3秒)与固定时间的相似ID的交集间隔 重叠:

time  id  angle  ...
0.0   a1  33.67  ...
0.1   a1  12.15  ...
0.2   a1  65.28  ...
0.3   a1  98.85  ...

0.0   c3  42.01  ...
0.1   c3  33.12  ...
0.2   c3  87.43  ...
0.3   c3  100.12 ...

到目前为止尝试过的代码:

#create pandas grouped by id
df1 = df.groupby(['id'], as_index=False)

输出:

time  id  angle ...
(0.0   a1  33.67
...
0.4   a1  11.11)

(0.0  b2  35.90
0.1   b2  15.35)

(0.0  c3  42.01
...
0.4   c3  83.22)

(0.0  d4  45.00)

但我只想 return 一个数据帧,其中 idtime 在固定间隔内相同,在上面的示例中为 .4 秒。

关于使用 pandas 数据帧实现这一点的相当简单的方法有什么想法吗?

如果需要按某些间隔过滤行 - 例如在 00.4 之间并获取重叠的所有 id 使用 boolean indexing with Series.between first, then DataFrame.pivot:

df1 = df[df['time'].between(0, 0.4)].pivot('time','id','angle')
print (df1)
id       a1     b2      c3    d4
time                            
0.0   33.67  35.90   42.01  45.0
0.1   12.15  15.35   33.12   NaN
0.2   65.28    NaN   87.43   NaN
0.3   98.85    NaN  100.12   NaN
0.4   11.11    NaN   83.22   NaN

非重叠 id 存在缺失值,因此按 DataFrame.any and reshape to 3 columns by DataFrame.unstack and Series.reset_index 删除包含任何 NaN 的列:

print (df1.dropna(axis=1))
id       a1      c3
time               
0.0   33.67   42.01
0.1   12.15   33.12
0.2   65.28   87.43
0.3   98.85  100.12
0.4   11.11   83.22

df2 = df1.dropna(axis=1).unstack().reset_index(name='angle')
print (df2)
   id  time   angle
0  a1   0.0   33.67
1  a1   0.1   12.15
2  a1   0.2   65.28
3  a1   0.3   98.85
4  a1   0.4   11.11
5  c3   0.0   42.01
6  c3   0.1   33.12
7  c3   0.2   87.43
8  c3   0.3  100.12
9  c3   0.4   83.22

有多种方法可以定义您需要的过滤器:

df.groupby('id').filter(lambda x: len(x) > 4)
    # OR
df.groupby('id').filter(lambda x: x['time'].eq(0.4).any())
    # OR
df.groupby('id').filter(lambda x: x['time'].max() == 0.4)

输出:

    time  id   angle
0    0.0  a1   33.67
2    0.0  c3   42.01
4    0.1  a1   12.15
6    0.1  c3   33.12
7    0.2  a1   65.28
8    0.2  c3   87.43
9    0.3  a1   98.85
10   0.3  c3  100.12
11   0.4  a1   11.11
12   0.4  c3   83.22