【问题标题】:Pandas Split DataFrame using row indexPandas 使用行索引拆分 DataFrame
【发布时间】:2019-04-22 19:13:56
【问题描述】:

我想使用行索引按奇数行拆分数据帧。

以下代码:

groups = df.groupby((np.arange(len(df.index))/l[1]).astype(int))

仅适用于统一的行数。

df

a b c  
1 1 1  
2 2 2  
3 3 3  
4 4 4  
5 5 5  
6 6 6  
7 7 7  

l = [2, 5, 7]

df1  
1 1 1  
2 2 2  

df2  
3,3,3  
4,4,4  
5,5,5  

df3  
6,6,6  
7,7,7  

df4  
8,8,8

【问题讨论】:

  • 你试过df.loc吗?
  • 你想随机分割还是有一些你想分割的索引?
  • 不是随机的,我想根据数组 l 进行拆分。前 2 行,然后从第 3 行到第 5 行,依此类推

标签: python pandas dataframe pandas-groupby


【解决方案1】:

我想这就是你要找的。,

l = [2, 5, 7]
dfs=[]
i=0
for val in l:
    if i==0:
        temp=df.iloc[:val]
        dfs.append(temp)
    elif i==len(l):
        temp=df.iloc[val]
        dfs.append(temp)        
    else:
        temp=df.iloc[l[i-1]:val]
        dfs.append(temp)
    i+=1

输出:

   a  b  c
0  1  1  1
1  2  2  2
   a  b  c
2  3  3  3
3  4  4  4
4  5  5  5
   a  b  c
5  6  6  6
6  7  7  7

另一种解决方案:

l = [2, 5, 7]
t= np.arange(l[-1])
l.reverse()
for val in l:
    t[:val]=val
temp=pd.DataFrame(t)
temp=pd.concat([df,temp],axis=1)
for u,v in temp.groupby(0):
    print v

输出:

   a  b  c  0
0  1  1  1  2
1  2  2  2  2
   a  b  c  0
2  3  3  3  5
3  4  4  4  5
4  5  5  5  5
   a  b  c  0
5  6  6  6  7
6  7  7  7  7

【讨论】:

    【解决方案2】:

    您可以创建一个数组用于通过 NumPy 进行索引:

    import pandas as pd, numpy as np
    
    df = pd.DataFrame(np.arange(24).reshape((8, 3)), columns=list('abc'))
    
    L = [2, 5, 7]
    idx = np.cumsum(np.in1d(np.arange(len(df.index)), L))
    
    for _, chunk in df.groupby(idx):
        print(chunk, '\n')
    
       a  b  c
    0  0  1  2
    1  3  4  5 
    
        a   b   c
    2   6   7   8
    3   9  10  11
    4  12  13  14 
    
        a   b   c
    5  15  16  17
    6  18  19  20 
    
        a   b   c
    7  21  22  23 
    

    您可以使用字典,而不是为每个数据帧定义一个新变量:

    d = dict(tuple(df.groupby(idx)))
    
    print(d[1])  # print second groupby value
    
        a   b   c
    2   6   7   8
    3   9  10  11
    4  12  13  14
    

    【讨论】:

      【解决方案3】:

      您可以使用列表推导式,首先对您的列表 l 稍作修改。

      print(df)
      
         a  b  c
      0  1  1  1
      1  2  2  2
      2  3  3  3
      3  4  4  4
      4  5  5  5
      5  6  6  6
      6  7  7  7
      7  8  8  8
      
      
      l = [2,5,7]
      l_mod = [0] + l + [max(l)+1]
      
      list_of_dfs = [df.iloc[l_mod[n]:l_mod[n+1]] for n in range(len(l_mod)-1)]
      

      输出:

      list_of_dfs[0]
      
         a  b  c
      0  1  1  1
      1  2  2  2
      
      list_of_dfs[1]
      
         a  b  c
      2  3  3  3
      3  4  4  4
      4  5  5  5
      
      list_of_dfs[2]
      
         a  b  c
      5  6  6  6
      6  7  7  7
      
      list_of_dfs[3]
      
         a  b  c
      7  8  8  8
      

      【讨论】:

      • 如果我错了请纠正我,但我认为修改后的列表应该是:l_mod = [0] + l + [len(df)]。现在,在这种情况下,max(l)+1 和 len(df) 重合,但如果泛化,您可能会丢失行。作为第二点,值得将它传递给set,以确保不存在重复的索引(比如[0] 2 次)。顺便说一句,很棒的解决方案,你得到了我的支持 :)
      • @N1h1l1sT 谢谢。是的,我认为您的概括是正确的。也许,您也可以使用这个原始列表来过滤数据框,但我同意您的假设。
      【解决方案4】:

      我认为这是你需要的:

      df = pd.DataFrame({'a': np.arange(1, 8),
                        'b': np.arange(1, 8),
                        'c': np.arange(1, 8)})
      df.head()
          a   b   c
      0   1   1   1
      1   2   2   2
      2   3   3   3
      3   4   4   4
      4   5   5   5
      5   6   6   6
      6   7   7   7
      
      last_check = 0
      dfs = []
      for ind in [2, 5, 7]:
          dfs.append(df.loc[last_check:ind-1])
          last_check = ind
      

      虽然列表解析比 for 循环更有效,但如果您的索引列表中没有模式,则 last_check 是必要的。

      dfs[0]
      
          a   b   c
      0   1   1   1
      1   2   2   2
      
      dfs[2]
      
          a   b   c
      5   6   6   6
      6   7   7   7
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-13
        • 2015-02-14
        • 1970-01-01
        • 2016-02-17
        相关资源
        最近更新 更多