pandas分组统计不重复值的数量

基础数据

数据格式如下,其中行只有一个值,所以每列均存在重复项(比如,一条策略含多个源地址,多个目标地址和多个端口情况)。

策略ID策略描述源地址目标地址端口开通时间结束时间
iddescriptionsrcdstportstet
1
2
3
4
5
6
7
8
import pandas as pd
df = pd.read_csv('/Users/zhengk/PycharmProjects/Mine/firewall/output/policy.csv', delimiter=';')
df.columns = ['id', 'description', 'src', 'dst', 'port', 'st', 'et']
df.head(2)
Out[3]:
id description src dst port st et
0 5 icmp Any Any PING forever forever
1 3 Tntrust2AllUntrust new_AG58 All_Untrust ANY forever forever

统计开通策略数最多的前5个源地址即对应的策略数

根据要求,只要按照源地址src分组,统计每个不同的src有多少个不重复的策略ID数,在进行排序即可。

  • 先筛选src和id两列进行计算

    1
    2
    3
    4
    5
    6
    7
    8
    df[['src', 'id']].head(5)
    Out[1]:
    src id
    0 Any 5
    1 new_AG58 3
    2 122.249.125.98/32 1973
    3 122.249.125.160/32 1974
    4 122.249.125.18/32 2100
  • 先使用groupby进行分组,使用nunique()来统计不重复的个数

    1
    2
    3
    4
    5
    6
    7
    8
    df[['src', 'id']].groupby('src')['id'].nunique().head(5)
    Out[2]:
    src
    122.249.125.1/32 2
    122.249.125.100/32 1
    122.249.125.101/32 38
    122.249.125.102/32 227
    122.249.125.103/32 255
  • 使用sort_values()对输出进行排序

    1
    2
    3
    4
    5
    6
    7
    8
    9
    df[['src', 'id']].groupby('src')['id'].nunique().sort_values(ascending=False).head(5)
    Out[3]:
    src
    122.249.125.71/32 1272
    122.249.125.209/32 529
    122.249.125.73/32 424
    122.249.125.113/32 391
    122.249.125.210/32 361
    Name: id, dtype: int64

拓展

  • DataFrame.nunique(*axis=0*, *dropna=True*)

    该函数根据axis轴参数统计非重复的个数,默认是按列来统计,如果指定axis=1则按行来统计。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    df1 = pd.DataFrame({'A': [1, 2, 3], 'B': [1, 1, 1]})
    df1
    Out[13]:
    A B
    0 1 1
    1 2 1
    2 3 1
    df1.nunique()
    Out[14]:
    A 3
    B 1
    dtype: int64
    df1.nunique(1)
    Out[15]:
    0 1
    1 2
    2 2
    dtype: int64

    http://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.nunique.html?highlight=nunique#pandas-dataframe-nunique

  • Series.unique()

    该函数返回非重复的具体值。是对series的操作,而不能直接操作dataframe。

    1
    2
    3
    4
    df1['A'].unique()
    Out[22]: array([1, 2, 3])
    df1['B'].unique()
    Out[23]: array([1])

    比如上例中,获取每个源地址可所有不重复的策略ID:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    df[['src', 'id']].groupby('src')['id'].unique().head(5)
    Out[24]:
    src
    122.249.125.1/32 [42690, 42691]
    122.249.125.100/32 [31563]
    122.249.125.101/32 [12458, 12488, 12536, 14394, 19550, 22348, 227...
    122.249.125.102/32 [12124, 12134, 12148, 12159, 12222, 12688, 126...
    122.249.125.103/32 [26711, 26713, 26714, 26719, 26721, 26736, 267...
    Name: id, dtype: object

    http://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.unique.html?highlight=unique#pandas-series-unique

  • DataFrame.sort_values(*by*, *axis=0*, *ascending=True*, *inplace=False*, *kind='quicksort'*, *na_position='last'*)

    该函数用于对指定axis轴中的值进行排序,默认为升序排列。需要注意的是其中的na_position参数,当源数据中存在空值时,确定空值的处理是很重要的,默认是空值放在最后。

    1
    2
    3
    4
    5
    6
    df1.sort_values(by=['A'], ascending=False)
    Out[26]:
    A B
    2 3 1
    1 2 1
    0 1 1

    http://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.sort_values.html#pandas-dataframe-sort-values