Python 如何获取pandas中每对唯一列的列值频率计数?

Python 如何获取pandas中每对唯一列的列值频率计数?,python,pandas,Python,Pandas,我有一个如下所示的数据框 data = [(datetime.datetime(2021, 2, 10, 7, 49, 7, 118658), u'12.100.90.10', u'100.100.12.1', u'LT_DOWN'), (datetime.datetime(2021, 2, 10, 7, 49, 14, 312273), u'12.100.90.10', u'100.100.12.1', u'LT_UP'), (datetime.datetime(2

我有一个如下所示的数据框

data = [(datetime.datetime(2021, 2, 10, 7, 49, 7, 118658), u'12.100.90.10', u'100.100.12.1', u'LT_DOWN'),
       (datetime.datetime(2021, 2, 10, 7, 49, 14, 312273), u'12.100.90.10', u'100.100.12.1', u'LT_UP'),
       (datetime.datetime(2021, 2, 10, 7, 49, 21, 535932), u'12.100.90.10', u'100.100.12.1', u'LT_UP'),
       (datetime.datetime(2021, 2, 10, 7, 50, 28, 725961), u'12.100.90.10', u'100.100.12.1', u'PL_DOWN'),
       (datetime.datetime(2021, 2, 10, 7, 50, 32, 450853), u'10.100.80.10', u'10.55.10.1', u'PL_LOW'),
       (datetime.datetime(2021, 2, 10, 7, 51, 32, 450853), u'10.10.80.10', u'10.55.10.1', u'MA_HIGH'),
       (datetime.datetime(2021, 2, 10, 7, 52, 34, 264042), u'10.10.80.10', u'10.55.10.1', u'PL_DOWN')]
start-end           10.10.80.10-10.55.10.1       10.100.80.10-10.55.10.1       12.100.90.10-100.100.12.1      
type                                     LT     MA     PL                      LT     MA     PL                            LT     MA     PL
date                                                                                                          
2021-02-10 07:49:00                      False  False  False                   False  False  False                         True   False  False
2021-02-10 07:50:00                      False  False  False                   False  False  True                          False  False  True
2021-02-10 07:51:00                      False  True  False                    False  False  False                         False  False  False
2021-02-10 07:52:00                      False  False  True                    False  False  False                         False  False  False
正如您所看到的,每分钟都会记录数据。我刚才在这里介绍了部分完整数据

这就是它在熊猫身上的样子

                        date         start           end     type
0 2021-02-10 07:49:07.118658  12.100.90.10  100.100.12.1  LT_DOWN
1 2021-02-10 07:49:14.312273  12.100.90.10  100.100.12.1    LT_UP
2 2021-02-10 07:49:21.535932  12.100.90.10  100.100.12.1    LT_UP
3 2021-02-10 07:50:28.725961  12.100.90.10  100.100.12.1  PL_DOWN
4 2021-02-10 07:50:32.450853  10.100.80.10    10.55.10.1   PL_LOW
5 2021-02-10 07:51:32.450853   10.10.80.10    10.55.10.1  MA_HIGH
6 2021-02-10 07:52:34.264042   10.10.80.10    10.55.10.1  PL_DOWN
首先,我想以分钟为单位获得
类型
列中每个值的计数(在
类型
列的值中,计数只应考虑
拆分的第一部分。因此它看起来像

          date     LT PL  MA
0 2021-02-10 07:49 3  0   0
1 2021-02-10 07:50 0  2   0
2 2021-02-10 07:51 0  0   1
3 2021-02-10 07:52 0  1   0
但上述数据并不能说明对于每一对唯一的
start
end
列值,
LT
PL
MA
(在
\uu
上拆分后)的计数

多亏了@Sayandip Dutta,他提供了以下解决方案()

下面是dataframe的外观

start-end           10.10.80.10-10.55.10.1       10.100.80.10-10.55.10.1       12.100.90.10-100.100.12.1      
type                                    LT MA PL                      LT MA PL                        LT MA PL
date                                                                                                          
2021-02-10 07:49:00                      0  0  0                       0  0  0                         3  0  0
2021-02-10 07:50:00                      0  0  0                       0  0  1                         0  0  1
2021-02-10 07:51:00                      0  1  0                       0  0  0                         0  0  0
2021-02-10 07:52:00                      0  0  1                       0  0  0                         0  0  0
将上面的转换为布尔值,如下所示

data = [(datetime.datetime(2021, 2, 10, 7, 49, 7, 118658), u'12.100.90.10', u'100.100.12.1', u'LT_DOWN'),
       (datetime.datetime(2021, 2, 10, 7, 49, 14, 312273), u'12.100.90.10', u'100.100.12.1', u'LT_UP'),
       (datetime.datetime(2021, 2, 10, 7, 49, 21, 535932), u'12.100.90.10', u'100.100.12.1', u'LT_UP'),
       (datetime.datetime(2021, 2, 10, 7, 50, 28, 725961), u'12.100.90.10', u'100.100.12.1', u'PL_DOWN'),
       (datetime.datetime(2021, 2, 10, 7, 50, 32, 450853), u'10.100.80.10', u'10.55.10.1', u'PL_LOW'),
       (datetime.datetime(2021, 2, 10, 7, 51, 32, 450853), u'10.10.80.10', u'10.55.10.1', u'MA_HIGH'),
       (datetime.datetime(2021, 2, 10, 7, 52, 34, 264042), u'10.10.80.10', u'10.55.10.1', u'PL_DOWN')]
start-end           10.10.80.10-10.55.10.1       10.100.80.10-10.55.10.1       12.100.90.10-100.100.12.1      
type                                     LT     MA     PL                      LT     MA     PL                            LT     MA     PL
date                                                                                                          
2021-02-10 07:49:00                      False  False  False                   False  False  False                         True   False  False
2021-02-10 07:50:00                      False  False  False                   False  False  True                          False  False  True
2021-02-10 07:51:00                      False  True  False                    False  False  False                         False  False  False
2021-02-10 07:52:00                      False  False  True                    False  False  False                         False  False  False
现在我想知道,对于每一对独特的
start
end
,对于
LT
MA
PL
True
的总计数是多少。所以我的最终数据帧应该是这样的

start         end           LT  MA  PL
10.10.80.10   10.55.10.1    0   1   1
10.100.80.10  10.55.10.1    0   0   1
12.100.90.10  100.100.12.1  1   0   1

我似乎不知道如何从交叉表中提取所需的信息。

您可以使用所引用的相同解决方案进行求和,并沿最后一个轴取消堆栈:

pd.crosstab(
       index=df['date'].dt.floor('1min'), 
       columns=[
           df['start'], 
           df['end'], 
           df['type'].str.extract(r'(\w+)_', expand=False)
      ], 
    ).astype(bool).sum().unstack(-1, fill_value=0)

type                       LT  MA  PL
start        end                     
10.10.80.10  10.55.10.1     0   1   1
10.100.80.10 10.55.10.1     0   0   1
12.100.90.10 100.100.12.1   1   0   1

可以使用所引用的相同解决方案进行求和,并沿最后一个轴取消堆栈:

pd.crosstab(
       index=df['date'].dt.floor('1min'), 
       columns=[
           df['start'], 
           df['end'], 
           df['type'].str.extract(r'(\w+)_', expand=False)
      ], 
    ).astype(bool).sum().unstack(-1, fill_value=0)

type                       LT  MA  PL
start        end                     
10.10.80.10  10.55.10.1     0   1   1
10.100.80.10 10.55.10.1     0   0   1
12.100.90.10 100.100.12.1   1   0   1

为什么行
12.100.90.10 100.100.12.1
LT
1
?我想应该是
3
@ShubhamSharma,我正在计算每种情况下
True
的总出现次数。如果您参考上一个数据框(就在它上面),
LT
对于这对
12.100.90.10 100.100.12.1
包含一个
True
。因此
True
的总计数是1。我真的不确定您是如何在数据框中得到布尔值的。也许您可以尝试下面@anky的答案。为什么
LT
value
1
对于
12.100.90.10 100.12.1
?我想应该是
3
@ShubhamSharma我正在计算每种情况下
True
的总出现次数。如果您参考上一个数据帧(就在它上面),
LT
对于这对
12.100.90.10 100.100.12.1
包含一个
True
。因此
True
的总计数为1。我真的不确定您是如何在数据帧中获得布尔值的。也许您可以尝试下面@anky的答案。嗨!感谢您回到我的问题。我尝试了您的解决方案,但您的结果似乎是正确的如果我更改了
LT
12.100.90.10 100.100.12.1
的计数为2的数据,则错误。以下是我认为您在
.dt.floor('1min')中遗漏的详细解释
这是您在之前的交叉表中所做的,并且给出了正确的计数。@苏维克雷,我明白了,我想我现在明白了。检查编辑,如果它有效。谢谢,伙计!这是我最终想要的。再次感谢您抽出时间来帮助我。我真的很感谢!嗨!谢谢您回到我的问题上来。我尝试了您的解决方案,但没有成功如果我更改
LT
12.100.90.10 100.100.12.1
的计数为2的数据,您的结果似乎是错误的。以下是我认为您在
.dt.floor('1min')上遗漏的详细解释
这是您在之前的交叉表中所做的,并且给出了正确的计数。@苏维克雷,我明白了,我想我现在明白了。检查编辑,如果它有效。谢谢,伙计!这终于是我想要的。再次感谢您抽出时间来帮助我。我真的非常感谢!