当前位置: 首页 > 知识库问答 >
问题:

从数据帧中删除包含空单元格的行

公良修竹
2023-03-14

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

>>> 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()选项无法识别缺少的值。

>>> df['Tenant'].isnull().sum()
    0

该列具有数据类型"Object"。这案子是怎么回事?如何删除租户失踪的记录?

共有3个答案

章宏峻
2023-03-14

value_counts默认省略NaN,所以您最有可能处理""。

所以你可以过滤掉它们

filter = df["Tenant"] != ""
dfNew = df[filter]
曹泉
2023-03-14

空字符串是falsy,这意味着您可以对bool值进行如下筛选:

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
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

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

.astype是一种矢量化操作,它比目前提供的所有选项都要快。至少,从我的测试来看。YMMV。

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

基准测试代码,供参考:

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)
姚嘉容
2023-03-14

如果某个值是np.nan对象,Pandas会将其识别为null,该对象将在数据帧中打印为nan。缺少的值可能是空字符串,Pandas无法识别为null。要解决此问题,可以使用replace(),将空stings(或空单元格中的任何内容)转换为np.nan对象,然后在数据帧上调用dropna(),删除租户为空的行。

为了演示,我们在租户列中创建了一个包含一些随机值和一些空字符串的数据帧:

>>> 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列中的任何空字符串,如下所示:

>>> 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

现在我们可以删除空值:

>>> 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
 类似资料:
  • 我一直试图创建一个宏来格式化从特定外部源复制的表,问题是,一些单元格似乎从右向左填充,剩余的空间向左填充空格:

  • 我相信这很简单,但找不到答案。我有一个数据帧df: 然后,我有另一个较小的数据框,其中包含单元格引用(行号和列号),引用df中应为空的特定单元格(即NA): 我如何用NA替换df中所有由cellRefs中的行和列引用引用的单元格?

  • 我是新的VBA和不是非常熟练的编程,所以我希望在这里得到一些帮助。 提前谢了。

  • 有没有人知道一个vba代码,如果a列中的任何单元格包含单词“total”,就可以删除整行?例如,A38包含“total”,则删除整行。下个月,单元格A44包含单词“total”,删除整行。诸如此类....谢谢!

  • 我正在尝试将csv文件中的值映射到RDD,但我收到以下错误,因为某些字段为空。 线程"main"中的异常org.apache.spark.SparkException:由于阶段失败而中止的作业:阶段0.0中的任务0失败1次,最近的失败:阶段0.0中丢失的任务0.0(TID 0,localhost,执行驱动程序):java.lang.NumberFormatException:空字符串 以下是我正在

  • 我有一个熊猫数据框,看起来像这样(但实际上要大得多): 我只想删除包含-500(2)和整列(f和g)的整行。我的数据框是自动生成的,我还不知道哪些列和行包含-500。 有人知道怎么做吗? 谢谢