python dataframe是否为空_关于python:从pandas DataFrame中删除包含空单元格的行

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

1

2

3

4

5

6

7

8

9

10

11In [67]: value_counts(Tenant,normalize=False)

Out[67]:

32320

Thunderhead 8170

Big Data Others 5700

Cloud Cruiser 5700

Partnerpedia 5700

Comcast 5700

SDP 5700

Agora 5700

dtype: int64

我正在尝试删除缺少租户的行,但是isull选项无法识别丢失的值。

1

2In [71]: df['Tenant'].isnull().sum()

Out[71]: 0

该列的数据类型为"对象"。 在这种情况下会发生什么? 如何在租户丢失的地方删除记录?

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

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

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

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

1

2

3

4

5

6

7

8

9

10

11

12

13

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

现在我们可以删除空值:

1

2

3

4

5

6

7

8

9

10

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

非常感谢,我会尝试一下,然后再回来!

@mcmath,有点好奇。 为什么可以导入pd.np.nan时导入numpy并使用np.nan?

@ propjk007,就像生活中的很多事情一样,有很多方法可以做很多事情

根据我的测试,看来df[df[Tenant].astype(bool)](假设没有空格字符-仅空字符串)比df.replace(, np.nan).dropna(subset=[Tenant])快

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

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

1

2filter = df["Tenant"] !=""

dfNew = df[filter]

@Bobs解决方案不适用于我。 df.dropna(subset = [tenant],inplace = True)有效。

对于那个很抱歉。 我以为您正在处理" s。您应该发布解决方案作为答案

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

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

1

2

3

4

5

6

7

8

9

10

11df = 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

1

2

3

4

5

6

7

8

9

10

11

12

13df['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:

1

2

3

4

5df[df['B'].str.strip().astype(bool)]

A B

0 0 foo

2 2 bar

4 4 xyz

比您想像的快

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

这是一个时序比较,我想了一些其他方法。

EXnza.png

基准测试代码,以供参考:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22import 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)

在某些情况下,单元格有空白,您看不到,请使用

1df['col'].replace(' ', np.nan, inplace=True)

将空白替换为NaN,然后

1df= df.dropna(subset=['col'])

您可以使用以下变体:

1

2

3

4

5

6

7

8import pandas as pd

vals = {

'name' : ['n1', 'n2', 'n3', 'n4', 'n5', 'n6', 'n7'],

'gender' : ['m', 'f', 'f', 'f', 'f', 'c', 'c'],

'age' : [39, 12, 27, 13, 36, 29, 10],

'education' : ['ma', None, 'school', None, 'ba', None, None]

}

df_vals = pd.DataFrame(vals) #converting dict to dataframe

这将输出(**-仅突出显示所需的行):

1

2

3

4

5

6

7

8age education gender name

0 39 ma m n1 **

1 12 None f n2

2 27 school f n3 **

3 13 None f n4

4 36 ba f n5 **

5 29 None c n6

6 10 None c n7

因此,要删除所有没有"教育"值的内容,请使用以下代码:

1df_vals = df_vals[~df_vals['education'].isnull()]

("?"表示不)

结果:

1

2

3

4age education gender name

0 39 ma m n1

2 27 school f n3

4 36 ba f n5

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值