【问题标题】:Splitting dataframe into chunks based on negative or np.nan value in specific column根据特定列中的负值或 np.nan 值将数据帧拆分为块
【发布时间】:2021-04-23 18:20:38
【问题描述】:

假设我有以下数据框:

import pandas as pd
import numpy as np

df = pd.DataFrame({'dif_seq': [np.nan, 1, 1, 1, 1, -23, 1, 1, 1, -4, 1, 1], 'data': range(12)})

df
Out[75]: 
    dif_seq  data
0       NaN     0
1       1.0     1
2       1.0     2
3       1.0     3
4       1.0     4
5     -23.0     5
6       1.0     6
7       1.0     7
8       1.0     8
9      -4.0     9
10      1.0    10
11      1.0    11

我想根据 df['dif_seq'] 中的值将 df 拆分为数据帧列表,如下所示(所有负值或 np.nan 值表示新 df 的开始):

    dif_seq  data
0       NaN     0
1       1.0     1
2       1.0     2
3       1.0     3
4       1.0     4

    dif_seq  data
5     -23.0     5
6       1.0     6
7       1.0     7
8       1.0     8

    dif_seq  data
9      -4.0     9
10      1.0    10
11      1.0    11

解决此问题的最佳方法是什么?我有一个非常大的数据集的类似问题。所以虽然这是一个小例子,但最快的路线是什么?

【问题讨论】:

    标签: python pandas dataframe split


    【解决方案1】:

    我想将 df 拆分为数据框列表

    您可以尝试使用条件累积和和 np.split:

    c = df['dif_seq'].lt(0)|df['dif_seq'].isna()
    #c= ~df.dif_seq.ge(0) : courtesy @MustafaAydın
    s = c.cumsum()
    l = np.split(df,np.where(np.diff(s)>0)[0]+1)
    #or for a dictionary: dict(iter(df.groupby(s)))
    

    >>l
    
    [   dif_seq  data
     0      NaN     0
     1      1.0     1
     2      1.0     2
     3      1.0     3
     4      1.0     4,
        dif_seq  data
     5    -23.0     5
     6      1.0     6
     7      1.0     7
     8      1.0     8,
         dif_seq  data
     9      -4.0     9
     10      1.0    10
     11      1.0    11]
    

    【讨论】:

    • 太棒了,c 可以一直写成~df.dif_seq.ge(0)吗?
    【解决方案2】:

    使用 diff 和 cumsum 创建 sub-groupby 键

    s = df['dif_seq'].diff()
    s = (s.notnull()& s.ne(0)).cumsum()
    s
    0     0
    1     0
    2     0
    3     0
    4     0
    5     1
    6     2
    7     2
    8     2
    9     3
    10    4
    11    4
    Name: dif_seq, dtype: int32
    d = {x : y for x , y in df.groupby(s)}
    

    【讨论】:

      【解决方案3】:

      创建一个系列而不是分配一个块,然后将其用作掩码。

      df = pd.DataFrame({'dif_seq': [np.nan, 1, 1, 1, 1, -23, 1, 1, 1, -4, 1, 1], 'data': range(12)})
      
      s = (df["dif_seq"].isna() | df["dif_seq"].lt(0)).cumsum()
      
      split = {f"df{i}":df.loc[s.eq(i)] for i in s.unique()}
      
      split
      

      输出

      {'df1':    dif_seq  data
       0      NaN     0
       1      1.0     1
       2      1.0     2
       3      1.0     3
       4      1.0     4,
       'df2':    dif_seq  data
       5    -23.0     5
       6      1.0     6
       7      1.0     7
       8      1.0     8,
       'df3':     dif_seq  data
       9      -4.0     9
       10      1.0    10
       11      1.0    11}
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-14
        • 1970-01-01
        • 1970-01-01
        • 2021-04-29
        • 2021-02-24
        • 1970-01-01
        • 2018-05-05
        • 1970-01-01
        相关资源
        最近更新 更多