2017-09-05 47 views
1

如果我的標題不是非常具有描述性,請道歉。但這是我正在嘗試實現: -根據羣組的頻率計數添加新欄目

我有一個數據幀與2個字段,即src端口和目標端口爲tcp流量。數據幀的csv轉儲看起來像這樣: -

srcp dstp 
55647 22 
22  55670 
2222 56354 
55670 22 
55670 22 
2222 56354 
56362 139 
22  55670 
22  55670 
56354 2222 
22  55670 
56354 2222 

coln 1是src端口,coln 2是目標端口。

我想看看對src port-destination端口並獲取它們的頻率並將其存儲在新的coln頻率中。換句話說,對於上面的例子,我想這樣做: -

55647 22 1 
    22 55670 6 
    2222 56354 4 
    55670 22 6 
    55670 22 6 
    2222 56354 4 
    56362 139 1 
    22 55670 6 
    22 55670 6 
    56354 2222 4 
    22 55670 6 
    56354 2222 4 

正如你可以看到,港口2222-5634擁有4頻率(因爲流量可以在任一方向流動,因此,他們需要確定作爲一個連接),因此在目標/ src端口中的任一個端口中的值2222-56354對應的頻率單元格中重複4的值。

由於仍然爬在蟒蛇階梯,我想知道我該如何實現這一目標。

+0

增加了一些定時使用sortgroupby我的【答案】(https://stackoverflow.com/a/46049704/4909087)。 –

回答

1

首先排序numpy.sort每行的所有值,然後用groupby功能transformsize

注意:差異sizecount之間count不計NaN值。

df['a'] = pd.DataFrame(np.sort(df.values, 1)).groupby([0,1])[0].transform('size') 
print (df) 
    srcp dstp a 
0 55647  22 1 
1  22 55670 6 
2 2222 56354 4 
3 55670  22 6 
4 55670  22 6 
5 2222 56354 4 
6 56362 139 1 
7  22 55670 6 
8  22 55670 6 
9 56354 2222 4 
10  22 55670 6 
11 56354 2222 4 

類似:

df['a'] = pd.DataFrame(np.sort(df.values, 1)) 
      .groupby(list(range(len(df.columns))))[0] 
      .transform('size') 
print (df) 

    srcp dstp a 
0 55647  22 1 
1  22 55670 6 
2 2222 56354 4 
3 55670  22 6 
4 55670  22 6 
5 2222 56354 4 
6 56362 139 1 
7  22 55670 6 
8  22 55670 6 
9 56354 2222 4 
10  22 55670 6 
11 56354 2222 4 
+0

感謝大家 - 我不確定我是否可以批准所有答案。這是一個很大的幫助。 – sunny

1

選項1

使用np.sort,但沒有df.apply

df['freq'] = pd.DataFrame(np.sort(df.values, 1), columns=df.columns)\ 
         .groupby(['srcp', 'dstp'])['srcp'].transform('count') 
df 

    srcp dstp freq 
0 55647  22  1 
1  22 55670  6 
2 2222 56354  4 
3 55670  22  6 
4 55670  22  6 
5 2222 56354  4 
6 56362 139  1 
7  22 55670  6 
8  22 55670  6 
9 56354 2222  4 
10  22 55670  6 
11 56354 2222  4 

選項2

您也可以使用處理這個問題frozenset小號

df2 = df.apply(frozenset, 1).reset_index()  
s = df2.groupby(df2.columns[-1]).index.transform('count') 
print(s) 

0  1 
1  6 
2  4 
3  6 
4  6 
5  4 
6  1 
7  6 
8  6 
9  4 
10 6 
11 4 

df['freq'] = s 
df 

    srcp dstp freq 
0 55647  22  1 
1  22 55670  6 
2 2222 56354  4 
3 55670  22  6 
4 55670  22  6 
5 2222 56354  4 
6 56362 139  1 
7  22 55670  6 
8  22 55670  6 
9 56354 2222  4 
10  22 55670  6 
11 56354 2222  4 

性能

1000 loops, best of 3: 1.82 ms per loop # jezrael #1 
1000 loops, best of 3: 1.84 ms per loop # jezrael #2 
1000 loops, best of 3: 1.78 ms per loop # mine #1 
100 loops, best of 3: 2.6 ms per loop # mine #2  
100 loops, best of 3: 3.96 ms per loop # John Galt 

大(df * 10000

100 loops, best of 3: 12.1 ms per loop # jezrael #1 
100 loops, best of 3: 11.9 ms per loop # jezrael #2 
100 loops, best of 3: 11.9 ms per loop # mine #1 
1 loop, best of 3: 3.51 s per loop  # mine #2 
1 loop, best of 3: 14.8 s per loop  # John Galt 
+0

謝謝你的時間,我的和你的答案第一次約。相同的時間(0.04毫秒比0.2毫秒的差異)。 – jezrael

1

你可以在列

In [1923]: df['freq'] = (df.apply(np.sort, 1) 
          .groupby(['srcp', 'dstp'])['srcp'] 
          .transform('size')) 

In [1924]: df 
Out[1924]: 
    srcp dstp freq 
0 55647  22  1 
1  22 55670  6 
2 2222 56354  4 
3 55670  22  6 
4 55670  22  6 
5 2222 56354  4 
6 56362 139  1 
7  22 55670  6 
8  22 55670  6 
9 56354 2222  4 
10  22 55670  6 
11 56354 2222  4