如何根据另一个在 Pandas 中拆分一个系列

问题描述

我在 python 熊猫中有两个系列。@H_502_1@

一个来自名为 values.csv文件中的值。它看起来像这样:@H_502_1@

time,value
0,10312435
9,45924523
11,43423434
20,42343552
...

一个叫做 breaks.csv,它看起来像这样:@H_502_1@

time
5
18
...

问题:我想根据 values.csv 中的值将 breaks.csv 拆分为单独的帧。@H_502_1@

在上面的例子中,第一个断点是 5,导致一个文件或集合包含 time \in [0,5] 中的所有条目,因此只有值 0,10312435。第二个断点是 18,因此第二批值应该在 (5,18] 内,即 9,4592452311,43423434 等等。@H_502_1@

在pandas(或者其他一些易于使用的python 包)中是否可以实现这样的功能?@H_502_1@

解决方法

您可以先从 breaks.time 形成 bin,然后使用 pd.cut 将类别分配给 values.time

import numpy as np

# intervals to fall into
bins = [-np.inf,*breaks.time,+np.inf]

# distinct labels of 0..N-1
labels = np.arange(len(bins) - 1)

# form a new column in `values` with assigned categories
values["cats"] = pd.cut(values.time,bins=bins,labels=labels)

此时 values 看起来像:

>>> values

   time     value cats
0     0  10312435    0
1     9  45924523    1
2    11  43423434    1
3    20  42343552    2

现在我们可以按 cats 分组,例如,形成一个数据框列表:

# no need for `cats` column anymore,so we drop it when putting in
frames_list = [frame.drop(columns="cats")
               for _,frame in values.groupby("cats")[["time","value"]]]

我们可以访问框架

>>> frames_list[0]

   time     value
0     0  10312435


>>> frames_list[1]

   time     value
1     9  45924523
2    11  43423434

>>> frames_list[2]

   time     value
3    20  42343552
,

我根据 Pandas split DataFrame by column value

得出以下结论
sim_dist_right = pandas.read_csv('sim/dist_right.csv',comment='#')
sim_round_indicator = pandas.read_csv('sim/round_indicator.csv',comment='#')

round_list = []
for index,row in sim_round_indicator.iterrows():
    print("splitting at " + str(row['time']))
    df_sep = sim_dist_right[sim_dist_right['time'] < row['time']]
    
    round_list.append(df_sep)
    print("separated a batch of " + str(len(df_sep)) + " elements")
    
    df_over = sim_dist_right[sim_dist_right['time'] >= row['time']]
    print(str(len(df_over)) + " elements over")
    
    sim_dist_right = df_over
    
print("splitted values into " + str(len(round_list)) + " batches")