Pandas将列转换为布尔类型并删除非真值行。

3
这是我的pandas dataframe的外观:
   id       text          country   datetime
0   1      hello,bye         USA    3/20/2016
1   0      good morning      UK     3/21/2016
2   x      wrong             USA    3/21/2016

我希望将id列变为布尔类型,如果值不是布尔类型,则删除该行。

我尝试过:

df=df[df['id'].bool()]

但是得到了 valueError:Series的真值不明确。请使用a.empty,a.bool(),a.item(),a.any()或a.all()。

2个回答

1

如果我理解正确,您可以尝试将列idto_numeric转换,然后与1进行比较:

print pd.to_numeric(df.id, errors='coerce') == 1
0     True
1    False
2    False
Name: id, dtype: bool

print df[pd.to_numeric(df.id, errors='coerce') == 1]
  id       text country   datetime
0  1  hello bye     USA  3/20/2016

如果你需要删除行,其中列id不是01,请使用isin

print df.id.isin(['0','1'])
0     True
1     True
2    False
Name: id, dtype: bool

print df[df.id.isin(['0','1'])]
  id          text country   datetime
0  1     hello bye     USA  3/20/2016
1  0  good morning      UK  3/21/2016

或者 to_numericnotnull
print pd.to_numeric(df.id, errors='coerce').notnull()
0     True
1     True
2    False
Name: id, dtype: bool

print df[pd.to_numeric(df.id, errors='coerce').notnull()]
  id          text country   datetime
0  1     hello bye     USA  3/20/2016
1  0  good morning      UK  3/21/2016

最后,您可以通过 replace 或双重 astype 将列 id 转换为 bool

print df.loc[df.id.isin(['0','1']),'id'].replace({'0': False, '1': True})
0     True
1    False
Name: id, dtype: bool

print df.loc[df.id.isin(['0','1']),'id'].astype(int).astype(bool)
0     True
1    False
Name: id, dtype: bool

print df.loc[pd.to_numeric(df.id, errors='coerce').notnull(),'id'].astype(int).astype(bool)
0     True
1    False
Name: id, dtype: bool

编辑:

时间,如果转换为bool的值仅为01

#len(df) = 30k
df = pd.concat([df]*10000).reset_index(drop=True)

In [628]: %timeit df.loc[np.in1d(df['id'], ['0','1']),'id'].map({'0': False, '1': True})
100 loops, best of 3: 2.19 ms per loop

In [629]: %timeit df.loc[np.in1d(df['id'], ['0','1']),'id'].replace({'0': False, '1': True})
The slowest run took 4.46 times longer than the fastest. This could mean that an intermediate result is being cached 
100 loops, best of 3: 4.72 ms per loop

In [630]: %timeit df.loc[df['id'].isin(['0','1']),'id'].map({'0': False, '1': True})
100 loops, best of 3: 2.78 ms per loop

In [631]: %timeit df.loc[df['id'].str.contains('0|1'),'id'].map({'0': False, '1': True})
10 loops, best of 3: 20 ms per loop

In [632]: %timeit df.loc[df['id'].isin(['0','1']),'id'].astype(int).astype(bool)
100 loops, best of 3: 9.5 ms per loop

最好使用numpy.in1dmap结合使用:

In [628]: %timeit df.loc[np.in1d(df['id'], ['0','1']),'id'].map({'0': False, '1': True})
100 loops, best of 3: 2.19 ms per loop

0
你可以使用 str.isdigit 来检查你的 id 列是否只包含数字,然后将其转换为数值类型再转换为布尔类型:
In [14]: df['id'].str.isdigit()
Out[14]:
0     True
1     True
2    False
Name: id, dtype: 

仅保留数字子集:

In [15]: df.loc[df['id'].str.isdigit(), 'id']
Out[15]:
0    1
1    0
Name: id, dtype: object

转换为布尔值:

In [17]: df.loc[df['id'].str.isdigit(), 'id'].astype(int).astype(bool)
Out[17]:
0     True
1    False
Name: id, dtype: bool

pd.to_numeric 的比较:

In [18]: %timeit pd.to_numeric(df.id, errors='coerce').notnull()
10000 loops, best of 3: 178 us per loop

In [19]: %timeit df['id'].str.isdigit()
10000 loops, best of 3: 128 us per loop

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接