Pandas:isin()用法及其注意事项
·
1 isin()用法
Pandas中的isin()方法可以同时判断数据是否与多个值相等,若与其中的某个值相等则返回True,否则则为False。具体使用方法如下:
import pandas as pd
data=pd.DataFrame([['foo','one','small',1],['foo','one','large',5],
['bar','one','small',10],['bar','two','samll',10],
['bar','two','large',50]],
columns=list('ABCD'))
#判断B列中的值是否为one和two
data_1=data['B'].isin(['one','two'])
#判断data中的所有值是否为foo和two,small
data_2=data.isin(['foo','small','two'])
#判断A列中的值是否为foo,C列中的值是否为small或large. 其他列返回False
data_3=data.isin({"A":['foo'],'C':['small','large']})
其结果依次如下:
isin()方法中处理能接收List/dict等数据类型时,还可以接收Series和DataFrame等类型,举例如下:
tmp_df=pd.DataFrame({'A':['foo','foo'],'D':[10,7]}) #其默认索引为0,1
tmp_df1=pd.DataFrame({'A':['foo','foo','bar'],'D':[10,10,50]},index=[2,3,4])
tmp_se=pd.Series(['foo','one',10],index=[0,1,2])
data_4=data.isin(tmp_df)
data_5=data.isin(tmp_df1)
#判断第0行是否为foo,第1行是否为one,第2行是否为10
data_6=data.isin(tmp_se)
- 其中data_4和data_5的结果如下图2:从data_4和data_5的结果可以看出:当isin()接收DataFrame类型数据时,其返回的结果相当于将两个DataFrame(一个是data,一个是isin中接收的参数)按照index和column对齐,若在相应位置上两个DataFrame的值相等则为True,否则为False。
- 其中data_6的结果如下图3:当isin()接收Series类型数据时,相当于按行判断是否与指定的值相等。
最后,关于isin()还有以下几点需要说明:
- isin()既是Series类型的方法,也是DataFrame的方法。所以这里data.isin()和data['B'].isin()都是合法的。
- 当isin()接收到的参数类型为Series和DataFrame时,Series的索引、DataFrame的索引及列名必须与原数据相同时对才能进行对比。
- isin()返回的结果为True或False,所以它能与loc方法连用,对数据进行筛选。可以使用如下代码将满足B列的值为one的数据筛选出来:
data_8=data[data['B'].isin(['one'])]
- 在过去的Pandas版本中isin()还有一个逆函数:notin()。但在最新版本中,这个函数已经删除了。可以使用~达到同样的效果。举例如下:
data_9=data[~(data['B'].isin(['one']))]
2 isin()能否判断空值np.nan
正如前文所述,isin()方法可以判断DataFrame/Series中的某个值是否等于给定值。那能不能使用isin()来判断其值是否等于空值呢?使用随机函数构建一个取值范围在10到100的100行2列的DataFrame,并将小于40的值修改为空值。然后统计DataFrame中取值为50和np.nan的数量。具体如下图4:
从图1中可以看出,红框框出来的部分完全相同,所以笔者当时就默认能在isin()函数中添加进np.nan。但是当遇到很大的数据量的时候,就不能这样做了,具体如图4:
由于出现了图4这种情况,所以我去看了Pandas中isin()函数的源码。发现isin()中针对不同情况,共计使用了四种不同函数来实现该功能,具体如表1(表1中给出的4个函数的功能都是依次判断x中的各个元素是否出现在y中,若出现则返回True,否则返回False):
情况 | 函数 |
---|---|
情况1元素个数>100w并且非Object类型 | numpy.in1d(x,y) |
不满足情况1并且数据为Int类型 | htable.ismember_int64(x, y) |
不满足情况1并且数据类Float类型 | htable.ismember_float64(x, y) |
其他 | htable.ismember_object(x, values) |
- 情况1: numpy.in1d()函数不能区分np.nan(因为numpy.in1d()中判断是否相等用的是==而不是is,而==是无法判断出np.nan的)。如下图5,该函数无法判断np.nan和np.nan是否相等,所以返回了False。
- 情况2/3/4:htable中三个函数都能识别出np.nan。
图5中的状况刚好满足情况1,而情况1中使用的函数无法识别出np.nan。为了安全起见,判断数据是否为空最好还是使用Pandas中的专用的判断方法:isnull()。
更多推荐
已为社区贡献5条内容
所有评论(0)