通过行值pandas

时间:2017-11-05 06:15:29

标签: python pandas dataframe count row

我有一个像这样的数据帧(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

如果具有特定/相同v1v2,则行位于同一块中。在这种情况下,行([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

谢谢!

3 个答案:

答案 0 :(得分:3)

使用groupby + count/size

df.groupby(['v1', 'v2']).v3.transform('count')

0     6.0
1     6.0
2     6.0
3     6.0
4     6.0
5     6.0
6     6.0
7     6.0
8     6.0
9     6.0
10    6.0
11    6.0
12    3.0
13    3.0
14    3.0
Name: v3, dtype: float64

使用遮罩过滤df

df = df[df.groupby(['v1', 'v2']).v3.transform('count').eq(6)]    # == 6
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

count不计算NaN,而size则计算import os import traceback for file in ['C:/AA/HA.csv', 'C:/AA1/HA1.csv']: try: os.remove(file) except OSError as e: traceback.print_exc() 。使用适合你的任何东西。

答案 1 :(得分:3)

我认为在var arr1 = [ ['a', 'b', 'c'], ['d', 'e'], ['f', 'g', 'h', 'i'] ], arr2 = [ [1, 2, 3], [5, 6], [7, 8, 9, 10] ], m = arr1.map(function(item, index) { let tempObj = {}; item.forEach(function(item2, index2) { tempObj[item2] = arr2[index][index2]; }); return tempObj; }); console.log(m)v1中没有v2,所以请使用transform + size

NaN

详情:

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

警告

考虑到组的数量,结果不能解决性能问题,这会对某些解决方案的时间产生很大的影响。

答案 2 :(得分:3)

您可以使用filter groupby方法:

In [11]: df.groupby(['v1', 'v2']).filter(lambda x: len(x) == 6)
Out[11]:
    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