蟒蛇& pandas - 如何在DataFrame中的列条件下计算频率?

时间:2016-09-07 12:20:35

标签: python pandas dataframe

我在DataFrame中有一系列名为frames的数据:

   NoUsager Sens IdVehiculeUtilise NoConducteur NoAdresse Fait  NoDemande Periods
0   000001   +        287Véh          000087     000079    1   42196000013 Matin 
1   000001   -        287Véh          000087     000079    1   42196000013 Matin 
2   000314   +        263Véh          000077     006470    1   42196000002 Matin 
3   002372   +        287Véh          000087     002932    1   42196000016 Matin 
4   000466   +        287Véh          000087     002932    1   42196000015 Matin 
5   000314   -        263Véh          000077     000456    1   42196000002 Matin 
6   000466   -        287Véh          000087     004900    1   42196000015 Matin 
7   002372   -        287Véh          000087     007072    1   42196000016 Matin 
8   002641   +        263Véh          000077     007225    1   42196000004 Soir 
9   002641   -        263Véh          000077     000889    1   42196000004 Soir 
10  000382   +        263Véh          000077     002095    1   42196000006 Soir 
11  002641   +        287Véh          000087     000889    1   42196000019 Soir 
12  000382   -        263Véh          000077     006168    1   42196000006 Soir 
13  002641   -        287Véh          000087     007225    1   42196000019 Soir 
14  001611   +        287Véh          000087     004236   -1   42196000021 Soir 
15  002785   +        263Véh          000077     007482    1   42196000007 Soir 
16  002372   +        287Véh          000087     007072    1   42196000022 Soir 
17  002785   -        263Véh          000077     007483    1   42196000007 Soir 
18  000466   +        287Véh          000087     004900    1   42196000023 Soir
19  000382   +        263Véh          000077     006168    1   42196000008 Soir 

对于每个Usager,根据SensPeriods,它们可以包含多个相关地址。我想知道所有Usager,他们有多少address以及每个地址的频率。 我使用frames.set_index(['NoUsager','NoAdresse'])使它看起来像:

修改

New pic

我不想要所有其他列,但只想要一个具有频率结果的新列。我能以哪种方式做到这一点?我可以使用pivot()来做吗?

任何帮助都将非常感谢!

1 个答案:

答案 0 :(得分:1)

我认为您需要groupby列,输出df为indexesNoUsagerSensPeriods}。然后需要添加列(NoAdresse)作为groupby中列表中的最后一项,该列由unstack转换为输出中的列。而且您需要按size汇总。

df = df.groupby(['NoUsager','Sens','Periods', 'NoAdresse']).size().unstack(fill_value=0)
print (df)
NoAdresse              79    456   889   2095  2932  4236  4900  6168  6470  \
NoUsager Sens Periods                                                         
1        +    Matin       1     0     0     0     0     0     0     0     0   
         -    Matin       1     0     0     0     0     0     0     0     0   
314      +    Matin       0     0     0     0     0     0     0     0     1   
         -    Matin       0     1     0     0     0     0     0     0     0   
382      +    Soir        0     0     0     1     0     0     0     1     0   
         -    Soir        0     0     0     0     0     0     0     1     0   
466      +    Matin       0     0     0     0     1     0     0     0     0   
              Soir        0     0     0     0     0     0     1     0     0   
         -    Matin       0     0     0     0     0     0     1     0     0   
1611     +    Soir        0     0     0     0     0     1     0     0     0   
2372     +    Matin       0     0     0     0     1     0     0     0     0   
              Soir        0     0     0     0     0     0     0     0     0   
         -    Matin       0     0     0     0     0     0     0     0     0   
2641     +    Soir        0     0     1     0     0     0     0     0     0   
         -    Soir        0     0     1     0     0     0     0     0     0   
2785     +    Soir        0     0     0     0     0     0     0     0     0   
         -    Soir        0     0     0     0     0     0     0     0     0   

NoAdresse              7072  7225  7482  7483  
NoUsager Sens Periods                          
1        +    Matin       0     0     0     0  
         -    Matin       0     0     0     0  
314      +    Matin       0     0     0     0  
         -    Matin       0     0     0     0  
382      +    Soir        0     0     0     0  
         -    Soir        0     0     0     0  
466      +    Matin       0     0     0     0  
              Soir        0     0     0     0  
         -    Matin       0     0     0     0  
1611     +    Soir        0     0     0     0  
2372     +    Matin       0     0     0     0  
              Soir        1     0     0     0  
         -    Matin       1     0     0     0  
2641     +    Soir        0     1     0     0  
         -    Soir        0     1     0     0  
2785     +    Soir        0     0     1     0  
         -    Soir        0     0     0     1  

如果需要重置索引:

df = df.groupby(['NoUsager','Sens','Periods', 'NoAdresse'])
       .size()
       .unstack(fill_value=0)
       .reset_index()
       .rename_axis(None, axis=1)

print (df)
    NoUsager Sens Periods  79  456  889  2095  2932  4236  4900  6168  6470  \
0          1    +   Matin   1    0    0     0     0     0     0     0     0   
1          1    -   Matin   1    0    0     0     0     0     0     0     0   
2        314    +   Matin   0    0    0     0     0     0     0     0     1   
3        314    -   Matin   0    1    0     0     0     0     0     0     0   
4        382    +    Soir   0    0    0     1     0     0     0     1     0   
5        382    -    Soir   0    0    0     0     0     0     0     1     0   
6        466    +   Matin   0    0    0     0     1     0     0     0     0   
7        466    +    Soir   0    0    0     0     0     0     1     0     0   
8        466    -   Matin   0    0    0     0     0     0     1     0     0   
9       1611    +    Soir   0    0    0     0     0     1     0     0     0   
10      2372    +   Matin   0    0    0     0     1     0     0     0     0   
11      2372    +    Soir   0    0    0     0     0     0     0     0     0   
12      2372    -   Matin   0    0    0     0     0     0     0     0     0   
13      2641    +    Soir   0    0    1     0     0     0     0     0     0   
14      2641    -    Soir   0    0    1     0     0     0     0     0     0   
15      2785    +    Soir   0    0    0     0     0     0     0     0     0   
16      2785    -    Soir   0    0    0     0     0     0     0     0     0   

    7072  7225  7482  7483  
0      0     0     0     0  
1      0     0     0     0  
2      0     0     0     0  
3      0     0     0     0  
4      0     0     0     0  
5      0     0     0     0  
6      0     0     0     0  
7      0     0     0     0  
8      0     0     0     0  
9      0     0     0     0  
10     0     0     0     0  
11     1     0     0     0  
12     1     0     0     0  
13     0     1     0     0  
14     0     1     0     0  
15     0     0     1     0  
16     0     0     0     1  

crosstab的另一个解决方案:

df = pd.crosstab([df.NoUsager,df.Sens,df.Periods], df.NoAdresse)
       .reset_index()
       .rename_axis(None, axis=1)

print (df)
    NoUsager Sens Periods  79  456  889  2095  2932  4236  4900  6168  6470  \
0          1    +   Matin   1    0    0     0     0     0     0     0     0   
1          1    -   Matin   1    0    0     0     0     0     0     0     0   
2        314    +   Matin   0    0    0     0     0     0     0     0     1   
3        314    -   Matin   0    1    0     0     0     0     0     0     0   
4        382    +    Soir   0    0    0     1     0     0     0     1     0   
5        382    -    Soir   0    0    0     0     0     0     0     1     0   
6        466    +   Matin   0    0    0     0     1     0     0     0     0   
7        466    +    Soir   0    0    0     0     0     0     1     0     0   
8        466    -   Matin   0    0    0     0     0     0     1     0     0   
9       1611    +    Soir   0    0    0     0     0     1     0     0     0   
10      2372    +   Matin   0    0    0     0     1     0     0     0     0   
11      2372    +    Soir   0    0    0     0     0     0     0     0     0   
12      2372    -   Matin   0    0    0     0     0     0     0     0     0   
13      2641    +    Soir   0    0    1     0     0     0     0     0     0   
14      2641    -    Soir   0    0    1     0     0     0     0     0     0   
15      2785    +    Soir   0    0    0     0     0     0     0     0     0   
16      2785    -    Soir   0    0    0     0     0     0     0     0     0   

    7072  7225  7482  7483  
0      0     0     0     0  
1      0     0     0     0  
2      0     0     0     0  
3      0     0     0     0  
4      0     0     0     0  
5      0     0     0     0  
6      0     0     0     0  
7      0     0     0     0  
8      0     0     0     0  
9      0     0     0     0  
10     0     0     0     0  
11     1     0     0     0  
12     1     0     0     0  
13     0     1     0     0  
14     0     1     0     0  
15     0     0     1     0  
16     0     0     0     1  

通过评论编辑:

我认为您只需要汇总size

df = df.groupby(['NoUsager','NoAdresse']).size().reset_index(name='Count')
print (df)
    NoUsager  NoAdresse  Count
0          1         79      2
1        314        456      1
2        314       6470      1
3        382       2095      1
4        382       6168      2
5        466       2932      1
6        466       4900      2
7       1611       4236      1
8       2372       2932      1
9       2372       7072      2
10      2641        889      2
11      2641       7225      2
12      2785       7482      1
13      2785       7483      1

如果需要设置索引,您可以使用其他解决方案 - rename Series名称,然后拨打to_frame

df = df.groupby(['NoUsager','NoAdresse']).size().rename('Count').to_frame()
                    Count
NoUsager NoAdresse       
1        79             2
314      456            1
         6470           1
382      2095           1
         6168           2
466      2932           1
         4900           2
1611     4236           1
2372     2932           1
         7072           2
2641     889            2
         7225           2
2785     7482           1
         7483           1

或添加set_index

df = df.groupby(['NoUsager','NoAdresse'])
       .size()
       .reset_index(name='Count')
       .set_index(['NoUsager','NoAdresse'])
print (df)
                    Count
NoUsager NoAdresse       
1        79             2
314      456            1
         6470           1
382      2095           1
         6168           2
466      2932           1
         4900           2
1611     4236           1
2372     2932           1
         7072           2
2641     889            2
         7225           2
2785     7482           1
         7483           1