布尔索引以将Falsey值保留为NaN

时间:2017-07-31 22:21:11

标签: python pandas dataframe nan

给定数据框:

                         Data
1                      246804
2                      135272
3                      898.01
4                     3453.33
5                       shine  
6                        add
7                         522
8                         Nan
9                      string
10                      29.11
11                        20  

我想要两个新列FloatsStrings,它们的长度与原始数据帧的长度相同。获取Floats列非常简单:

In [176]: pd.to_numeric(df.Data, errors='coerce')
Out[176]: 
1     246804.00
2     135272.00
3        898.01
4       3453.33
5           NaN
6           NaN
7        522.00
8           NaN
9           NaN
10        29.11
11        20.00
Name: Data, dtype: float64

正如您所看到的,非浮动被强制转移到NaN,这正是我想要的。

要获得字符串,这就是我的工作:

In [177]: df[df.Data.str.isalpha()]
Out[177]: 
     Data
5   shine
6     add
8     Nan
9  string

但正如您所看到的,它不会将非String值保留为NaN。我想要这样的东西:

1                       NaN
2                       NaN
3                       NaN
4                       NaN
5                       shine  
6                       add
7                       NaN
8                       Nan (not NaN)
9                       string
10                      NaN
11                      NaN  

我怎么能这样做?

3 个答案:

答案 0 :(得分:5)

要获得Strings,您可以在Data列上使用布尔索引,并找到Floats为空的位置。

df['Floats'] = pd.to_numeric(df.Data, errors='coerce')
df['Strings'] = df.Data.loc[df.Floats.isnull()]  # Optional: .astype(str)

>>> df
# Output:
#        Data     Floats Strings
# 1    246804  246804.00     NaN
# 2    135272  135272.00     NaN
# 3    898.01     898.01     NaN
# 4   3453.33    3453.33     NaN
# 5     shine        NaN   shine
# 6       add        NaN     add
# 7       522     522.00     NaN
# 8       Nan        NaN     Nan
# 9    string        NaN  string
# 10    29.11      29.11     NaN
# 11       20      20.00     NaN

答案 1 :(得分:3)

floats = pd.to_numeric(df.Data, 'coerce')
pd.DataFrame(dict(
    floats=floats,
    strings=df.Data.mask(floats.notnull())
))

       floats strings
1   246804.00     NaN
2   135272.00     NaN
3      898.01     NaN
4     3453.33     NaN
5         NaN   shine
6         NaN     add
7      522.00     NaN
8         NaN     Nan
9         NaN  string
10      29.11     NaN
11      20.00     NaN

您甚至可以通过传递替代

mask内使其更加明显
floats = pd.to_numeric(df.Data, 'coerce')
pd.DataFrame(dict(
    floats=floats,
    strings=df.Data.mask(floats.notnull(), '')
))

       floats strings
1   246804.00        
2   135272.00        
3      898.01        
4     3453.33        
5         NaN   shine
6         NaN     add
7      522.00        
8         NaN     Nan
9         NaN  string
10      29.11        
11      20.00        

答案 2 :(得分:3)

怎么样

df.Data.where(pd.to_numeric(df.Data, errors='coerce').isnull())
Out[186]: 
      Data
1      NaN
2      NaN
3      NaN
4      NaN
5    shine
6      add
7      NaN
8      Nan #not NaN
9   string
10     NaN
11     NaN

或以df.Data.str.isalpha()

为基础
df['Data'].where(df['Data'].str.isalpha())