首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >从pandas DataFrame中删除包含空单元格的行

从pandas DataFrame中删除包含空单元格的行
EN

Stack Overflow用户
提问于 2015-03-28 13:30:49
回答 5查看 344.5K关注 0票数 125

我有一个pd.DataFrame,它是通过解析一些excel电子表格创建的。其中一列具有空单元格。例如,下面是该列频率的输出,有32320条记录缺少租户的值。

代码语言:javascript
复制
>>> value_counts(Tenant, normalize=False)
                              32320
    Thunderhead                8170
    Big Data Others            5700
    Cloud Cruiser              5700
    Partnerpedia               5700
    Comcast                    5700
    SDP                        5700
    Agora                      5700
    dtype: int64

我正在尝试删除缺少租户的行,但是.isnull()选项无法识别缺少的值。

代码语言:javascript
复制
>>> df['Tenant'].isnull().sum()
    0

该列的数据类型为"Object“。在这种情况下发生了什么?如何删除缺少租户的记录?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2015-03-28 15:46:29

如果一个值是一个np.nan对象,那么Pandas将把它识别为null,这将在DataFrame中打印为NaN。您缺少的值可能是空字符串,Pandas不会将其识别为null。要解决这个问题,可以使用replace()将空字符串(或空单元格中的任何内容)转换为np.nan对象,然后在DataFrame上调用dropna()来删除具有null租户的行。

为了演示,我们在Tenants列中创建一个包含一些随机值和一些空字符串的DataFrame:

代码语言:javascript
复制
>>> import pandas as pd
>>> import numpy as np
>>> 
>>> df = pd.DataFrame(np.random.randn(10, 2), columns=list('AB'))
>>> df['Tenant'] = np.random.choice(['Babar', 'Rataxes', ''], 10)
>>> print df

          A         B   Tenant
0 -0.588412 -1.179306    Babar
1 -0.008562  0.725239         
2  0.282146  0.421721  Rataxes
3  0.627611 -0.661126    Babar
4  0.805304 -0.834214         
5 -0.514568  1.890647    Babar
6 -1.188436  0.294792  Rataxes
7  1.471766 -0.267807    Babar
8 -1.730745  1.358165  Rataxes
9  0.066946  0.375640         

现在我们用np.nan对象替换Tenants列中的所有空字符串,如下所示:

代码语言:javascript
复制
>>> df['Tenant'].replace('', np.nan, inplace=True)
>>> print df

          A         B   Tenant
0 -0.588412 -1.179306    Babar
1 -0.008562  0.725239      NaN
2  0.282146  0.421721  Rataxes
3  0.627611 -0.661126    Babar
4  0.805304 -0.834214      NaN
5 -0.514568  1.890647    Babar
6 -1.188436  0.294792  Rataxes
7  1.471766 -0.267807    Babar
8 -1.730745  1.358165  Rataxes
9  0.066946  0.375640      NaN

现在我们可以删除空值:

代码语言:javascript
复制
>>> df.dropna(subset=['Tenant'], inplace=True)
>>> print df

          A         B   Tenant
0 -0.588412 -1.179306    Babar
2  0.282146  0.421721  Rataxes
3  0.627611 -0.661126    Babar
5 -0.514568  1.890647    Babar
6 -1.188436  0.294792  Rataxes
7  1.471766 -0.267807    Babar
8 -1.730745  1.358165  Rataxes
票数 232
EN

Stack Overflow用户

发布于 2019-06-22 02:20:53

Pythonic + Pandorable:df[df['col'].astype(bool)]

空字符串是假的,这意味着您可以像这样过滤布尔值:

代码语言:javascript
复制
df = pd.DataFrame({
    'A': range(5),
    'B': ['foo', '', 'bar', '', 'xyz']
})
df
   A    B
0  0  foo
1  1     
2  2  bar
3  3     
4  4  xyz
代码语言:javascript
复制
df['B'].astype(bool)                                                                                                                      
0     True
1    False
2     True
3    False
4     True
Name: B, dtype: bool

df[df['B'].astype(bool)]                                                                                                                  
   A    B
0  0  foo
2  2  bar
4  4  xyz

如果您的目标是不仅要删除空字符串,而且还要删除仅包含空格的字符串,请提前使用str.strip

代码语言:javascript
复制
df[df['B'].str.strip().astype(bool)]
   A    B
0  0  foo
2  2  bar
4  4  xyz

比你想象的更快

.astype是一个矢量化操作,这比到目前为止提出的每个选项都要快。至少从我的测试来看是这样。YMMV.

这是一个时间上的比较,我提出了一些我能想到的其他方法。

基准测试代码,供参考:

代码语言:javascript
复制
import pandas as pd
import perfplot

df1 = pd.DataFrame({
    'A': range(5),
    'B': ['foo', '', 'bar', '', 'xyz']
})

perfplot.show(
    setup=lambda n: pd.concat([df1] * n, ignore_index=True),
    kernels=[
        lambda df: df[df['B'].astype(bool)],
        lambda df: df[df['B'] != ''],
        lambda df: df[df['B'].replace('', np.nan).notna()],  # optimized 1-col
        lambda df: df.replace({'B': {'': np.nan}}).dropna(subset=['B']),  
    ],
    labels=['astype', "!= ''", "replace + notna", "replace + dropna", ],
    n_range=[2**k for k in range(1, 15)],
    xlabel='N',
    logx=True,
    logy=True,
    equality_check=pd.DataFrame.equals)
票数 84
EN

Stack Overflow用户

发布于 2015-03-29 00:19:17

默认情况下,value_counts省略了NaN,因此您最有可能处理的是"“。

所以你可以像这样过滤掉它们

代码语言:javascript
复制
filter = df["Tenant"] != ""
dfNew = df[filter]
票数 38
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29314033

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档