通过行值熊猫的某些组合计算行

发布于 2021-01-29 15:05:35

我有一个像这样的数据框(df):

  v1    v2  v3
   0    -30 -15
   0    -30 -7.5
   0    -30 -11.25
   0    -30 -13.125
   0    -30 -14.0625
   0    -30 -13.59375
   0    -10 -5
   0    -10 -7.5
   0    -10 -6.25
   0    -10 -5.625
   0    -10 -5.9375
   0    -10 -6.09375
   0    -5  -2.5
   0    -5  -1.25
   0    -5  -1.875

如果具有肯定/相同v1和行,则这些行位于同一块中v2。在这种情况下,带有的行([0,-30], [0,-10], [0,-5])。我想将行拆分为块,并计算该块中的行数。如果行的长度不是6,则删除整个块,否则,保留该块。

我的粗略代码:

v1_ls = df.v1.unique()
v2_ls = df.v2.unique()
for i, j in v1_ls, v2_ls: 
   chunk[i] = df[(df['v1'] == v1_ls[i]) & df['v2'] == v2_ls[j]]

   if len(chunk[i])!= 6:
      df = df[df != chunk[i]]
   else:
      pass

预期输出:

  v1    v2  v3
   0    -30 -15
   0    -30 -7.5
   0    -30 -11.25
   0    -30 -13.125
   0    -30 -14.0625
   0    -30 -13.59375
   0    -10 -5
   0    -10 -7.5
   0    -10 -6.25
   0    -10 -5.625
   0    -10 -5.9375
   0    -10 -6.09375

谢谢!

关注者
0
被浏览
62
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    我认为,在v1v2没有NaNS,所以使用transform+
    size

    df = df[df.groupby(['v1', 'v2'])['v2'].transform('size') == 6]
    print (df)
        v1  v2        v3
    0    0 -30 -15.00000
    1    0 -30  -7.50000
    2    0 -30 -11.25000
    3    0 -30 -13.12500
    4    0 -30 -14.06250
    5    0 -30 -13.59375
    6    0 -10  -5.00000
    7    0 -10  -7.50000
    8    0 -10  -6.25000
    9    0 -10  -5.62500
    10   0 -10  -5.93750
    11   0 -10  -6.09375
    

    详情:

    print (df.groupby(['v1', 'v2'])['v2'].transform('size') == 6)
    0      True
    1      True
    2      True
    3      True
    4      True
    5      True
    6      True
    7      True
    8      True
    9      True
    10     True
    11     True
    12    False
    13    False
    14    False
    Name: v2, dtype: bool
    

    不幸的filter是真的很慢,因此如果需要更好的性能,请使用transform

    np.random.seed(123)
    N = 1000000
    L = list('abcdefghijkl') 
    df = pd.DataFrame({'v1': np.random.choice(L, N),
                       'v2':np.random.randint(10000,size=N),
                       'value':np.random.randint(1000,size=N),
                       'value2':np.random.randint(5000,size=N)})
    df = df.sort_values(['v1','v2']).reset_index(drop=True)
    print (df.head(10))
    
    In [290]: %timeit df.groupby(['v1', 'v2']).filter(lambda x: len(x) == 6)
    1 loop, best of 3: 12.1 s per loop
    
    In [291]: %timeit df[df.groupby(['v1', 'v2'])['v2'].transform('size') == 6]
    1 loop, best of 3: 176 ms per loop
    
    In [292]: %timeit df[df.groupby(['v1', 'v2']).v2.transform('count').eq(6)]
    10 loops, best of 3: 175 ms per loop
    

    N = 1000000
    
    ngroups = 1000
    
    df = pd.DataFrame(dict(A = np.random.randint(0,ngroups,size=N),B=np.random.randn(N)))
    
    In [299]: %timeit df.groupby('A').filter(lambda x: len(x) > 1000)
    1 loop, best of 3: 330 ms per loop
    
    In [300]: %timeit df[df.groupby(['A'])['A'].transform('size') > 1000]
    10 loops, best of 3: 101 ms per loop
    

    警告

    给定组数,结果不能解决性能问题,这对于其中一些解决方案的时序会产生很大影响。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看