【问题标题】:how to split a series in pandas based on another如何根据另一个拆分熊猫系列
【发布时间】:2021-09-10 12:26:06
【问题描述】:

我在 python pandas 中有两个系列。

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

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

另一个叫breaks.csv,看起来像这样:

time
5
18
...

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

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

在 pandas(或者其他一些易于使用的 python 包)中是否可能出现这种情况?

【问题讨论】:

    标签: python pandas filesplitting


    【解决方案1】:

    您可以先从breaks.time 形成垃圾箱,然后使用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
    

    【讨论】:

      【解决方案2】:

      我根据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")
      

      【讨论】:

      • 使用.iterrows() 可以很好地工作,但效率不是很高。你可以试试上面的pd.cut
      猜你喜欢
      • 1970-01-01
      • 2023-01-20
      • 2020-12-11
      • 2020-06-22
      • 2023-01-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多