如何在pandas crosstab数据框中显示列的空值?

0 投票
2 回答
5431 浏览
提问于 2025-04-18 10:54

我一直在使用pandas库,并利用crosstab来创建一个频率数据框,以便处理数据。在下面的代码中,我读取了一个csv文件,创建了一个数据框,然后生成了一个crosstab,这就是频率数据框。接着,我获取了数据的一个交叉部分,以提取出一些列和下面的数据。

def dataforgraphs():
    d = readcsv()
    df = DataFrame(d)
    d1=df[1]
    d0=df[0]
    d2=df[2]
    d3=df[3]
    d4=df[4]


    cta = pd.crosstab(d0,[d2,d1,d3],rownames=['Date'],colnames=['RigStat','Prov','Obj'],   margins=False)

    ndfABA= ndf.xs('AB', level='Prov', axis=1)
    ABrigs = ndfAB.xs(['BIT','GAS','OIL'],axis=1)

现在我遇到的问题是,无法提取一个假设的列,这个列应该包含所有没有标记为'BIT'、'GAS'或'OIL'的空白值。在Excel的透视表中,我可以通过勾选(空白)框来选择要包含在透视表中的列。我想在这里做同样的事情,以获取所有空白值的频率计数。

有什么建议吗?

目前我得到的输出只有指定的三个列和下面的频率。

            OIL   GAS   BIT
Date  
01-01-2007   1     6     3
01-02-2007   2     4     4
01-03-2007   1     6     3
01-04-2007   5     6     4
01-05-2007   1     7     3
01-06-2007   6     6     6
01-07-2007   1     8     3
01-08-2007   5     6     6
01-09-2007   1     6     3
01-10-2007   1     7     3

相反,我希望得到的结果是,包括一个列,显示所有没有标记为OIL、GAS或BIT(或者说没有标记为任何东西)的空白值。

            OIL   GAS   BIT  "blank'
Date  
01-01-2007   1     6     3     10
01-02-2007   2     4     4     11
01-03-2007   1     6     3     12
01-04-2007   5     6     4     10
01-05-2007   1     7     3      1
01-06-2007   6     6     6      4
01-07-2007   1     8     3      5
01-08-2007   5     6     6      2
01-09-2007   1     6     3      5
01-10-2007   1     7     3      2

输入到pandas crosstab数据框中的数据结构如下:

Date         Obj  Operator  Type  Address
01-01-2007   OIL   ABC      HZ    112 W Ave
01-01-2007   GAS   ABC      HZ    112 W Ave
01-01-2007   GAS   ABV      HZ    113 W Ave
01-01-2007   BIT   NCH      HZ    114 W Ave
01-01-2007         CNR      HZ    115 W Ave
01-02-2007   OIL   CNRL     HZ    112 W Ave
01-02-2007   OIL   CNRL     HZ    112 W Ave
01-02-2007   OIL   CNRL     HZ    112 W Ave
01-03-2007         CNRL     HZ    112 W Ave
01-03-2007         CNRL     HZ    112 W Ave

从这里,pandas crosstab会创建一个频率表,记录OIL、GAS、BIT按日期的频率,但我找不到如何获取空白值的计数。注意有些列没有列出Obj。这些值在crosstab中没有被捕获,我希望能够查询到这些值。

有什么建议吗?

2 个回答

0

重新整理你的混淆矩阵,并在那些位置填上零。

df_confusion = pd.crosstab(y_actual, y_predicted).reindex(columns=[0,1],index=[0,1], fill_value=0)

indexcolumns属性中指定行和列,并设置fill_value = 0来填充零。

3

一种方法是用你想要的字符串(比如'blank')来填充NaN值,这样它们也会被计算在内:

In [23]: df
Out[23]: 
         Date  Obj Operator Type    Address
0  01-01-2007  OIL      ABC   HZ  112 W Ave
1  01-01-2007  GAS      ABC   HZ  112 W Ave
2  01-01-2007  GAS      ABV   HZ  113 W Ave
3  01-01-2007  BIT      NCH   HZ  114 W Ave
4  01-01-2007  NaN      CNR   HZ  115 W Ave
5  01-02-2007  OIL     CNRL   HZ  112 W Ave
6  01-02-2007  OIL     CNRL   HZ  112 W Ave
7  01-02-2007  OIL     CNRL   HZ  112 W Ave
8  01-03-2007  NaN     CNRL   HZ  112 W Ave
9  01-03-2007  NaN     CNRL   HZ  112 W Ave

In [24]: pd.crosstab(df['Date'], df['Obj'])
Out[24]: 
Obj         BIT  GAS  OIL
Date                     
01-01-2007    1    2    1
01-02-2007    0    0    3

In [25]: df2 = df.fillna('blank')

In [26]: pd.crosstab(df2['Date'], df2['Obj'])
Out[26]: 
Obj         BIT  GAS  OIL  blank
Date                            
01-01-2007    1    2    1      1
01-02-2007    0    0    3      0
01-03-2007    0    0    0      2

交叉表实际上就是根据你提供的行和列的值进行分组(这些值会变成行和列的索引),然后统计这些值出现的频率。

撰写回答