【问题标题】:Best way to split a DataFrame given an edge给定边缘分割 DataFrame 的最佳方法
【发布时间】:2013-04-28 09:23:29
【问题描述】:

假设我有以下 DataFrame:

   a         b
0  A  1.516733
1  A  0.035646
2  A -0.942834
3  B -0.157334
4  A  2.226809
5  A  0.768516
6  B -0.015162
7  A  0.710356
8  A  0.151429

我需要根据“边缘 B”对它进行分组;这意味着这些组将是:

   a         b
0  A  1.516733
1  A  0.035646
2  A -0.942834
3  B -0.157334

4  A  2.226809
5  A  0.768516
6  B -0.015162

7  A  0.710356
8  A  0.151429

就是这样。每当我在“a”列中找到“B”时,我都想拆分我的 DataFrame。

我目前的解决方案是:

#create the dataframe
s = pd.Series(['A','A','A','B','A','A','B','A','A'])
ss = pd.Series(np.random.randn(9))
dff = pd.DataFrame({"a":s,"b":ss})

#my solution
count  = 0
ls = []
for i in s:
    if i=="A":
        ls.append(count)
    else:
        ls.append(count)
        count+=1
dff['grpb']=ls

我得到了数据框:

    a   b           grpb
0   A   1.516733    0
1   A   0.035646    0
2   A   -0.942834   0
3   B   -0.157334   0
4   A   2.226809    1
5   A   0.768516    1
6   B   -0.015162   1
7   A   0.710356    2
8   A   0.151429    2

然后我可以使用dff.groupby('grpb') 拆分。

有没有更有效的方法使用 pandas 函数来做到这一点?

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    怎么样:

    df.groupby((df.a == "B").shift(1).fillna(0).cumsum())
    

    例如:

    >>> df
       a         b
    0  A -1.957118
    1  A -0.906079
    2  A -0.496355
    3  B  0.552072
    4  A -1.903361
    5  A  1.436268
    6  B  0.391087
    7  A -0.907679
    8  A  1.672897
    >>> gg = list(df.groupby((df.a == "B").shift(1).fillna(0).cumsum()))
    >>> pprint.pprint(gg)
    [(0,
         a         b
    0  A -1.957118
    1  A -0.906079
    2  A -0.496355
    3  B  0.552072),
     (1,    a         b
    4  A -1.903361
    5  A  1.436268
    6  B  0.391087),
     (2,    a         b
    7  A -0.907679
    8  A  1.672897)]
    

    (我没有费心摆脱索引;如果您愿意,可以使用 [g for k, g in df.groupby(...)]。)

    【讨论】:

      【解决方案2】:

      这是一个单线:

      zip(*dff.groupby(pd.rolling_median((1*(dff['a']=='B')).cumsum(),3,True)))[-1]
      
      [   1         2
      0  A  1.516733
      1  A  0.035646
      2  A -0.942834
      3  B -0.157334,
          1         2
      4  A  2.226809
      5  A  0.768516
      6  B -0.015162,
          1         2
      7  A  0.710356
      8  A  0.151429]
      

      【讨论】:

        【解决方案3】:

        另一种选择是:

        In [36]: dff
        Out[36]:
           a         b
        0  A  0.689785
        1  A -0.374623
        2  A  0.517337
        3  B  1.549259
        4  A  0.576892
        5  A -0.833309
        6  B -0.209827
        7  A -0.150917
        8  A -1.296696
        
        In [37]: dff['grpb'] = np.NaN
        
        In [38]: breaks = dff[dff.a == 'B'].index
        
        In [39]: dff['grpb'][breaks] = range(len(breaks))
        
        In [40]: dff.fillna(method='bfill').fillna(len(breaks))
        Out[40]:
           a         b  grpb
        0  A  0.689785     0
        1  A -0.374623     0
        2  A  0.517337     0
        3  B  1.549259     0
        4  A  0.576892     1
        5  A -0.833309     1
        6  B -0.209827     1
        7  A -0.150917     2
        8  A -1.296696     2
        

        或者使用itertools 创建“grpb”也是一种选择。

        【讨论】:

          【解决方案4】:
              def vGroup(dataFrame, edgeCondition, groupName='autoGroup'):
              groupNum = 0
              dataFrame[groupName] = ''
          
              #loop over each row
              for inx, row in dataFrame.iterrows():
                      if edgeCondition[inx]:
                          dataFrame.ix[inx, groupName] = 'edge'
                          groupNum += 1
                      else:
                          dataFrame.ix[inx, groupName] = groupNum
          
              return dataFrame[groupName]
          
          vGroup(df, df[0] == '  ')
          

          【讨论】:

          • 使用 iterrows() 循环遍历每一行;然后你可以做任何你想做的事。我认为这种方法更灵活。
          猜你喜欢
          • 2021-04-24
          • 2012-11-16
          • 1970-01-01
          • 1970-01-01
          • 2016-10-21
          • 2013-08-28
          • 1970-01-01
          • 1970-01-01
          • 2021-02-09
          相关资源
          最近更新 更多